Skip to content
This repository was archived by the owner on Apr 28, 2024. It is now read-only.

Commit 2afee24

Browse files
authored
Merge pull request #5 from salemzii/master
feat(transport): Add websocket transport;
2 parents f93267d + 90ca14a commit 2afee24

File tree

4 files changed

+124
-4
lines changed

4 files changed

+124
-4
lines changed

go.mod

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,14 @@ module go.neonxp.dev/jsonrpc2
33
go 1.18
44

55
require (
6+
github.com/gobwas/ws v1.1.0
67
github.com/qri-io/jsonschema v0.2.1
7-
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29
8+
golang.org/x/sync v0.1.0
89
)
910

10-
require github.com/qri-io/jsonpointer v0.1.1 // indirect
11+
require (
12+
github.com/gobwas/httphead v0.1.0 // indirect
13+
github.com/gobwas/pool v0.2.1 // indirect
14+
github.com/qri-io/jsonpointer v0.1.1 // indirect
15+
golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d // indirect
16+
)

go.sum

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2+
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
3+
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
4+
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
5+
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
6+
github.com/gobwas/ws v1.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA=
7+
github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0=
28
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
39
github.com/qri-io/jsonpointer v0.1.1 h1:prVZBZLL6TW5vsSB9fFHFAMBLI4b0ri5vribQlTJiBA=
410
github.com/qri-io/jsonpointer v0.1.1/go.mod h1:DnJPaYgiKu56EuDp8TU5wFLdZIcAnb/uH9v37ZaMV64=
@@ -8,5 +14,7 @@ github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
814
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
915
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
1016
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
11-
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 h1:w8s32wxx3sY+OjLlv9qltkLU5yvJzxjjgiHWLjdIcw4=
12-
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
17+
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
18+
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
19+
golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d h1:MiWWjyhUzZ+jvhZvloX6ZrUsdEghn8a64Upd8EMHglE=
20+
golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

rpc/options.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,9 @@ func WithLogger(l Logger) Option {
4242
s.logger = l
4343
}
4444
}
45+
46+
func WithMiddlewares(mws ...Middleware) Option {
47+
return func(s *RpcServer) {
48+
s.middlewares = append(s.middlewares, mws...)
49+
}
50+
}

transport/websockets.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
//Package rpc provides abstract rpc server
2+
//
3+
//Copyright (C) 2022 Alexander Kiryukhin <[email protected]>
4+
//
5+
//This file is part of go.neonxp.dev/jsonrpc2 project.
6+
//
7+
//This program is free software: you can redistribute it and/or modify
8+
//it under the terms of the GNU General Public License as published by
9+
//the Free Software Foundation, either version 3 of the License, or
10+
//(at your option) any later version.
11+
//
12+
//This program is distributed in the hope that it will be useful,
13+
//but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
//GNU General Public License for more details.
16+
//
17+
//You should have received a copy of the GNU General Public License
18+
//along with this program. If not, see <https://www.gnu.org/licenses/>.
19+
20+
package transport
21+
22+
import (
23+
"context"
24+
"crypto/tls"
25+
"net"
26+
"net/http"
27+
"time"
28+
29+
websocket "github.com/gobwas/ws"
30+
"github.com/gobwas/ws/wsutil"
31+
)
32+
33+
type WebSocket struct {
34+
Bind string
35+
TLS *tls.Config
36+
CORSOrigin string
37+
Parallel bool
38+
ReadDeadline, WriteDeadline time.Duration //Set custom timeout for future read and write calls
39+
}
40+
41+
func (ws *WebSocket) WithReadDealine() bool { return ws.ReadDeadline != 0 }
42+
func (ws *WebSocket) WithWriteDealine() bool { return ws.WriteDeadline != 0 }
43+
44+
func (ws *WebSocket) Run(ctx context.Context, resolver Resolver) error {
45+
srv := http.Server{
46+
Addr: ws.Bind,
47+
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
48+
wsconn, _, _, err := websocket.UpgradeHTTP(r, w)
49+
if err != nil {
50+
return
51+
}
52+
53+
defer func() {
54+
wsconn.Close()
55+
}()
56+
57+
if ws.WithReadDealine() {
58+
wsconn.SetReadDeadline(time.Now().Add(ws.ReadDeadline * time.Second))
59+
}
60+
61+
if ws.WithWriteDealine() {
62+
wsconn.SetWriteDeadline(time.Now().Add(ws.WriteDeadline * time.Second))
63+
}
64+
65+
for {
66+
67+
// read message from connection
68+
_, reader, err := wsutil.NextReader(wsconn, websocket.StateServerSide)
69+
if err != nil {
70+
return
71+
}
72+
73+
// create writer object that implements io.WriterCloser interface
74+
writer := wsutil.NewWriter(wsconn, websocket.StateServerSide, websocket.OpText)
75+
76+
resolver.Resolve(ctx, reader, writer, ws.Parallel)
77+
78+
if err := writer.Flush(); err != nil {
79+
return
80+
}
81+
82+
}
83+
84+
}),
85+
86+
BaseContext: func(l net.Listener) context.Context {
87+
return ctx
88+
},
89+
}
90+
91+
go func() {
92+
<-ctx.Done()
93+
srv.Close()
94+
}()
95+
96+
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
97+
return err
98+
}
99+
return nil
100+
}

0 commit comments

Comments
 (0)