Skip to content

Commit aee15f7

Browse files
committed
data framing
1 parent 69e6f5b commit aee15f7

12 files changed

+529
-31
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2020 Meng Huang
3+
Copyright (c) 2020 Meng Huang ([email protected])
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 122 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,122 @@
1-
# websocket
1+
# websocket
2+
websocket protocol
3+
## Get started
4+
5+
### Install
6+
```
7+
go get github.com/hslam/websocket
8+
```
9+
### Import
10+
```
11+
import "github.com/hslam/websocket"
12+
```
13+
### Usage
14+
#### Example
15+
16+
**server.go**
17+
```go
18+
package main
19+
20+
import (
21+
"github.com/hslam/mux"
22+
"github.com/hslam/websocket"
23+
"log"
24+
"net/http"
25+
"strings"
26+
)
27+
28+
func main() {
29+
m := mux.New()
30+
m.HandleFunc("/upper", func(w http.ResponseWriter, r *http.Request) {
31+
conn := websocket.Accept(w, r)
32+
ServeConn(conn)
33+
}).GET()
34+
log.Fatal(http.ListenAndServe(":8080", m))
35+
}
36+
37+
func ServeConn(conn *websocket.Conn) {
38+
for {
39+
var message string
40+
err := conn.ReadMessage(&message)
41+
if err != nil {
42+
break
43+
}
44+
conn.WriteMessage(strings.ToUpper(string(message)))
45+
}
46+
}
47+
```
48+
49+
**client.go**
50+
```go
51+
package main
52+
53+
import (
54+
"fmt"
55+
"github.com/hslam/websocket"
56+
"time"
57+
)
58+
59+
func main() {
60+
conn, err := websocket.Dial("127.0.0.1:8080", "/upper")
61+
if err != nil {
62+
panic(err)
63+
}
64+
defer conn.Close()
65+
for i := 0; i < 3; i++ {
66+
conn.WriteMessage([]byte("Hello websocket"))
67+
var message string
68+
err := conn.ReadMessage(&message)
69+
if err != nil {
70+
break
71+
}
72+
fmt.Println(message)
73+
time.Sleep(time.Second)
74+
}
75+
}
76+
```
77+
78+
**Output**
79+
```
80+
HELLO WEBSOCKET
81+
HELLO WEBSOCKET
82+
HELLO WEBSOCKET
83+
```
84+
85+
**client.html**
86+
```html
87+
<!DOCTYPE html>
88+
<html>
89+
<head>
90+
<meta charset="utf-8"/>
91+
<title>Websocket</title>
92+
</head>
93+
<body>
94+
<h1>UPPER</h1>
95+
<form><p>string: <input id="content" type="text" placeholder="input string"></p></form>
96+
<label id="result">result:</label><br><br>
97+
<button onclick="send()">upper</button>
98+
<script type="text/javascript">
99+
var ws = null;
100+
var wsuri = "ws://127.0.0.1:8080/upper";
101+
ws = new WebSocket(wsuri);
102+
ws.onmessage = function(e) {
103+
var result = document.getElementById('result');
104+
result.innerHTML = "result:" + e.data;
105+
}
106+
function send() {
107+
var msg = document.getElementById('content').value;
108+
ws.send(msg);
109+
}
110+
</script>
111+
</body>
112+
</html>
113+
```
114+
115+
### License
116+
This package is licensed under a MIT license (Copyright (c) 2020 Meng Huang)
117+
118+
119+
### Authors
120+
websocket was written by Meng Huang.
121+
122+

conn.go

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,56 @@
11
package websocket
22

33
import (
4+
"math/rand"
45
"net"
56
"time"
67
)
78

89
type Conn struct {
9-
isClient bool
10-
conn net.Conn
11-
key string
12-
accept string
13-
path string
14-
address string
10+
isClient bool
11+
random *rand.Rand
12+
conn net.Conn
13+
key string
14+
accept string
15+
path string
16+
address string
17+
readBuffer []byte
18+
buffer []byte
19+
connBuffer []byte
20+
frameBuffer []byte
1521
}
1622

1723
func (c *Conn) Read(b []byte) (n int, err error) {
18-
return c.conn.Read(b)
24+
if len(c.connBuffer) > 0 {
25+
if len(b) >= len(c.connBuffer) {
26+
copy(b, c.connBuffer)
27+
c.connBuffer = c.connBuffer[len(b):]
28+
return len(c.connBuffer), nil
29+
}
30+
copy(b, c.connBuffer[:len(b)])
31+
c.connBuffer = c.connBuffer[len(b):]
32+
return len(b), nil
33+
}
34+
f, err := c.readFrame()
35+
if err != nil {
36+
return 0, err
37+
}
38+
if len(b) >= len(f.PayloadData) {
39+
copy(b, f.PayloadData)
40+
return len(f.PayloadData), nil
41+
}
42+
copy(b, f.PayloadData[:len(b)])
43+
c.connBuffer = append(c.connBuffer, f.PayloadData[len(b):]...)
44+
return len(b), nil
1945
}
2046

2147
func (c *Conn) Write(b []byte) (n int, err error) {
22-
return c.conn.Write(b)
48+
f := &frame{FIN: 1, Opcode: BinaryFrame, PayloadData: b}
49+
err = c.writeFrame(f)
50+
if err != nil {
51+
return 0, err
52+
}
53+
return len(b), nil
2354
}
2455

2556
func (c *Conn) Close() error {

example/.DS_Store

6 KB
Binary file not shown.

example/client/client.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package main
22

33
import (
4-
"bufio"
54
"fmt"
65
"github.com/hslam/websocket"
7-
"io"
86
"time"
97
)
108

@@ -14,14 +12,14 @@ func main() {
1412
panic(err)
1513
}
1614
defer conn.Close()
17-
reader := bufio.NewReader(conn)
1815
for i := 0; i < 3; i++ {
19-
conn.Write([]byte("Hello websocket\n"))
20-
message, err := reader.ReadString('\n')
21-
if err != nil || err == io.EOF {
16+
conn.WriteMessage([]byte("Hello websocket"))
17+
var message string
18+
err := conn.ReadMessage(&message)
19+
if err != nil {
2220
break
2321
}
24-
fmt.Print(message)
22+
fmt.Println(message)
2523
time.Sleep(time.Second)
2624
}
2725
}

example/client/client.html

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8"/>
5+
<title>Websocket</title>
6+
</head>
7+
<body>
8+
<h1>UPPER</h1>
9+
<form><p>string: <input id="content" type="text" placeholder="input string"></p></form>
10+
<label id="result">result:</label><br><br>
11+
<button onclick="send()">upper</button>
12+
<script type="text/javascript">
13+
var ws = null;
14+
var wsuri = "ws://127.0.0.1:8080/upper";
15+
ws = new WebSocket(wsuri);
16+
ws.onmessage = function(e) {
17+
var result = document.getElementById('result');
18+
result.innerHTML = "result:" + e.data;
19+
}
20+
function send() {
21+
var msg = document.getElementById('content').value;
22+
ws.send(msg);
23+
}
24+
</script>
25+
</body>
26+
</html>

example/main.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package main
22

33
import (
4-
"bufio"
54
"github.com/hslam/mux"
65
"github.com/hslam/websocket"
7-
"io"
86
"log"
97
"net/http"
108
"strings"
@@ -20,12 +18,12 @@ func main() {
2018
}
2119

2220
func ServeConn(conn *websocket.Conn) {
23-
reader := bufio.NewReader(conn)
2421
for {
25-
message, err := reader.ReadString('\n')
26-
if err != nil || err == io.EOF {
22+
var message string
23+
err := conn.ReadMessage(&message)
24+
if err != nil {
2725
break
2826
}
29-
conn.Write([]byte(strings.ToUpper(string(message))))
27+
conn.WriteMessage(strings.ToUpper(string(message)))
3028
}
3129
}

0 commit comments

Comments
 (0)