@@ -12,15 +12,18 @@ import (
1212 "runtime/debug"
1313 "time"
1414
15+ "github.com/gorilla/websocket"
16+ "github.com/pkg/errors"
1517 "github.com/sourcegraph/go-langserver/langserver"
1618 "github.com/sourcegraph/jsonrpc2"
19+ wsjsonrpc2 "github.com/sourcegraph/jsonrpc2/websocket"
1720
1821 _ "net/http/pprof"
1922)
2023
2124var (
22- mode = flag .String ("mode" , "stdio" , "communication mode (stdio|tcp)" )
23- addr = flag .String ("addr" , ":4389" , "server listen address (tcp)" )
25+ mode = flag .String ("mode" , "stdio" , "communication mode (stdio|tcp|websocket )" )
26+ addr = flag .String ("addr" , ":4389" , "server listen address (tcp or websocket )" )
2427 trace = flag .Bool ("trace" , false , "print all requests and responses" )
2528 logfile = flag .String ("logfile" , "" , "also log to this file (in addition to stderr)" )
2629 printVersion = flag .Bool ("version" , false , "print version and exit" )
@@ -101,8 +104,6 @@ func run(cfg langserver.Config) error {
101104 connOpt = append (connOpt , jsonrpc2 .LogMessages (log .New (logW , "" , 0 )))
102105 }
103106
104- handler := langserver .NewHandler (cfg )
105-
106107 switch * mode {
107108 case "tcp" :
108109 lis , err := net .Listen ("tcp" , * addr )
@@ -111,18 +112,54 @@ func run(cfg langserver.Config) error {
111112 }
112113 defer lis .Close ()
113114
114- log .Println ("langserver-go: listening on" , * addr )
115+ log .Println ("langserver-go: listening for TCP connections on" , * addr )
116+
117+ connectionCount := 0
118+
115119 for {
116120 conn , err := lis .Accept ()
117121 if err != nil {
118122 return err
119123 }
120- jsonrpc2 .NewConn (context .Background (), jsonrpc2 .NewBufferedStream (conn , jsonrpc2.VSCodeObjectCodec {}), handler , connOpt ... )
124+ connectionCount = connectionCount + 1
125+ connectionID := connectionCount
126+ log .Printf ("langserver-go: received incoming connection #%d\n " , connectionID )
127+ jsonrpc2Connection := jsonrpc2 .NewConn (context .Background (), jsonrpc2 .NewBufferedStream (conn , jsonrpc2.VSCodeObjectCodec {}), langserver .NewHandler (cfg ), connOpt ... )
128+ go func () {
129+ <- jsonrpc2Connection .DisconnectNotify ()
130+ log .Printf ("langserver-go: connection #%d closed\n " , connectionID )
131+ }()
121132 }
122133
134+ case "websocket" :
135+ mux := http .NewServeMux ()
136+ upgrader := websocket.Upgrader {CheckOrigin : func (r * http.Request ) bool { return true }}
137+
138+ connectionCount := 0
139+
140+ mux .HandleFunc ("/" , func (w http.ResponseWriter , request * http.Request ) {
141+ connection , err := upgrader .Upgrade (w , request , nil )
142+ if err != nil {
143+ log .Println ("error upgrading HTTP to WebSocket:" , err )
144+ http .Error (w , errors .Wrap (err , "could not upgrade to WebSocket" ).Error (), http .StatusBadRequest )
145+ return
146+ }
147+ defer connection .Close ()
148+ connectionCount = connectionCount + 1
149+ connectionID := connectionCount
150+ log .Printf ("langserver-go: received incoming connection #%d\n " , connectionID )
151+ <- jsonrpc2 .NewConn (context .Background (), wsjsonrpc2 .NewObjectStream (connection ), langserver .NewHandler (cfg ), connOpt ... ).DisconnectNotify ()
152+ log .Printf ("langserver-go: connection #%d closed\n " , connectionID )
153+ })
154+
155+ log .Println ("langserver-go: listening for WebSocket connections on" , * addr )
156+ err := http .ListenAndServe (* addr , mux )
157+ log .Println (errors .Wrap (err , "HTTP server" ))
158+ return err
159+
123160 case "stdio" :
124161 log .Println ("langserver-go: reading on stdin, writing on stdout" )
125- <- jsonrpc2 .NewConn (context .Background (), jsonrpc2 .NewBufferedStream (stdrwc {}, jsonrpc2.VSCodeObjectCodec {}), handler , connOpt ... ).DisconnectNotify ()
162+ <- jsonrpc2 .NewConn (context .Background (), jsonrpc2 .NewBufferedStream (stdrwc {}, jsonrpc2.VSCodeObjectCodec {}), langserver . NewHandler ( cfg ) , connOpt ... ).DisconnectNotify ()
126163 log .Println ("connection closed" )
127164 return nil
128165
0 commit comments