Skip to content

Commit 0e78812

Browse files
committed
Improve JSON API
Closes #50
1 parent e16f830 commit 0e78812

File tree

5 files changed

+65
-20
lines changed

5 files changed

+65
-20
lines changed

README.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,17 @@ fn := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
4545
}
4646
defer c.Close(websocket.StatusInternalError, "")
4747

48+
jc := websocket.JSONConn{
49+
Conn: c,
50+
}
51+
4852
ctx, cancel := context.WithTimeout(r.Context(), time.Second*10)
4953
defer cancel()
5054

5155
v := map[string]interface{}{
5256
"my_field": "foo",
5357
}
54-
err = websocket.WriteJSON(ctx, c, v)
58+
err = jc.Write(ctx, v)
5559
if err != nil {
5660
log.Printf("failed to write json: %v", err)
5761
return
@@ -73,7 +77,7 @@ For a production quality example that shows off the low level API, see the [echo
7377

7478
```go
7579
ctx := context.Background()
76-
ctx, cancel := context.WithTimeout(ctx, time.Second*10)
80+
ctx, cancel := context.WithTimeout(ctx, time.Minute)
7781
defer cancel()
7882

7983
c, _, err := websocket.Dial(ctx, "ws://localhost:8080",
@@ -84,8 +88,12 @@ if err != nil {
8488
}
8589
defer c.Close(websocket.StatusInternalError, "")
8690

91+
jc := websocket.JSONConn{
92+
Conn: c,
93+
}
94+
8795
var v interface{}
88-
err = websocket.ReadJSON(ctx, c, v)
96+
err = jc.Read(ctx, v)
8997
if err != nil {
9098
log.Fatalf("failed to read json: %v", err)
9199
}

datatype_string.go

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

example_test.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,17 @@ func ExampleAccept() {
8888
}
8989
defer c.Close(websocket.StatusInternalError, "")
9090

91+
jc := websocket.JSONConn{
92+
Conn: c,
93+
}
94+
9195
ctx, cancel := context.WithTimeout(r.Context(), time.Second*10)
9296
defer cancel()
9397

9498
v := map[string]interface{}{
9599
"my_field": "foo",
96100
}
97-
err = websocket.WriteJSON(ctx, c, v)
101+
err = jc.Write(ctx, v)
98102
if err != nil {
99103
log.Printf("failed to write json: %v", err)
100104
return
@@ -123,8 +127,12 @@ func ExampleDial() {
123127
}
124128
defer c.Close(websocket.StatusInternalError, "")
125129

130+
jc := websocket.JSONConn{
131+
Conn: c,
132+
}
133+
126134
var v interface{}
127-
err = websocket.ReadJSON(ctx, c, v)
135+
err = jc.Read(ctx, v)
128136
if err != nil {
129137
log.Fatalf("failed to read json: %v", err)
130138
}

json.go

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,28 @@ import (
77
"golang.org/x/xerrors"
88
)
99

10-
// ReadJSON reads a json message from c into v.
11-
func ReadJSON(ctx context.Context, c *Conn, v interface{}) error {
12-
typ, r, err := c.ReadMessage(ctx)
10+
// JSONConn wraps around a Conn with JSON helpers.
11+
type JSONConn struct {
12+
Conn *Conn
13+
}
14+
15+
// Read reads a json message into v.
16+
func (jc JSONConn) Read(ctx context.Context, v interface{}) error {
17+
err := jc.read(ctx, v)
1318
if err != nil {
1419
return xerrors.Errorf("failed to read json: %w", err)
1520
}
21+
return nil
22+
}
23+
24+
func (jc *JSONConn) read(ctx context.Context, v interface{}) error {
25+
typ, r, err := jc.Conn.ReadMessage(ctx)
26+
if err != nil {
27+
return err
28+
}
1629

17-
if typ != Text {
18-
return xerrors.Errorf("unexpected frame type for json (expected TextFrame): %v", typ)
30+
if typ != DataText {
31+
return xerrors.Errorf("unexpected frame type for json (expected DataText): %v", typ)
1932
}
2033

2134
r.Limit(131072)
@@ -24,25 +37,33 @@ func ReadJSON(ctx context.Context, c *Conn, v interface{}) error {
2437
d := json.NewDecoder(r)
2538
err = d.Decode(v)
2639
if err != nil {
27-
return xerrors.Errorf("failed to read json: %w", err)
40+
return xerrors.Errorf("failed to decode json: %w", err)
2841
}
2942
return nil
3043
}
3144

32-
// WriteJSON writes the json message v into c.
33-
func WriteJSON(ctx context.Context, c *Conn, v interface{}) error {
34-
w := c.MessageWriter(Text)
45+
// Write writes the json message v.
46+
func (jc JSONConn) Write(ctx context.Context, v interface{}) error {
47+
err := jc.write(ctx, v)
48+
if err != nil {
49+
return xerrors.Errorf("failed to write json: %w", err)
50+
}
51+
return nil
52+
}
53+
54+
func (jc JSONConn) write(ctx context.Context, v interface{}) error {
55+
w := jc.Conn.MessageWriter(DataText)
3556
w.SetContext(ctx)
3657

3758
e := json.NewEncoder(w)
3859
err := e.Encode(v)
3960
if err != nil {
40-
return xerrors.Errorf("failed to write json: %w", err)
61+
return xerrors.Errorf("failed to encode json: %w", err)
4162
}
4263

4364
err = w.Close()
4465
if err != nil {
45-
return xerrors.Errorf("failed to write json: %w", err)
66+
return err
4667
}
4768
return nil
4869
}

websocket_test.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,14 @@ func TestHandshake(t *testing.T) {
173173
ctx, cancel := context.WithTimeout(r.Context(), time.Second*5)
174174
defer cancel()
175175

176+
jc := websocket.JSONConn{
177+
Conn: c,
178+
}
179+
176180
v := map[string]interface{}{
177181
"anmol": "wowow",
178182
}
179-
err = websocket.WriteJSON(ctx, c, v)
183+
err = jc.Write(ctx, v)
180184
if err != nil {
181185
return err
182186
}
@@ -191,8 +195,12 @@ func TestHandshake(t *testing.T) {
191195
}
192196
defer c.Close(websocket.StatusInternalError, "")
193197

198+
jc := websocket.JSONConn{
199+
Conn: c,
200+
}
201+
194202
var v interface{}
195-
err = websocket.ReadJSON(ctx, c, &v)
203+
err = jc.Read(ctx, &v)
196204
if err != nil {
197205
return err
198206
}

0 commit comments

Comments
 (0)