blob: 0aaf55e69bfe61f24e8c3d80502549e1b83a0cfb [file] [log] [blame]
Nicolas LaCassefea49162014-11-17 15:41:03 -08001// +build nacl
2
3package websocket
4
5import (
6 "net"
7 "net/url"
8 "runtime/ppapi"
9 "sync"
10 "time"
11)
12
13// Ppapi instance which must be set before the Dial is called.
14var PpapiInstance ppapi.Instance
15
16func WebsocketConn(address string, ws *ppapi.WebsocketConn) net.Conn {
17 return &wrappedConn{
18 address: address,
19 ws: ws,
20 }
21}
22
23type wrappedConn struct {
24 address string
25 ws *ppapi.WebsocketConn
26 readLock sync.Mutex
27 writeLock sync.Mutex
28 currBuffer []byte
29}
30
Cosmos Nicolaou3c50ac42014-12-23 07:40:19 -080031func Dial(protocol, address string, timeout time.Duration) (net.Conn, error) {
Nicolas LaCassefea49162014-11-17 15:41:03 -080032 inst := PpapiInstance
33 u, err := url.Parse("ws://" + address)
34 if err != nil {
35 return nil, err
36 }
37
38 ws, err := inst.DialWebsocket(u.String())
39 if err != nil {
40 return nil, err
41 }
42 return WebsocketConn(address, ws), nil
43}
44
45func (c *wrappedConn) Read(b []byte) (int, error) {
46 c.readLock.Lock()
47 defer c.readLock.Unlock()
48
49 var err error
50 if len(c.currBuffer) == 0 {
51 c.currBuffer, err = c.ws.ReceiveMessage()
52 if err != nil {
Nicolas LaCasse6ad3ff12014-11-24 19:08:05 -080053 return 0, err
Nicolas LaCassefea49162014-11-17 15:41:03 -080054 }
55 }
56
57 n := copy(b, c.currBuffer)
58 c.currBuffer = c.currBuffer[n:]
59 return n, nil
60}
61
62func (c *wrappedConn) Write(b []byte) (int, error) {
63 c.writeLock.Lock()
64 defer c.writeLock.Unlock()
65 if err := c.ws.SendMessage(b); err != nil {
66 return 0, err
67 }
68 return len(b), nil
69}
70
71func (c *wrappedConn) Close() error {
72 return c.ws.Close()
73}
74
75func (c *wrappedConn) LocalAddr() net.Addr {
76 return websocketAddr{s: c.address}
77}
78
79func (c *wrappedConn) RemoteAddr() net.Addr {
80 return websocketAddr{s: c.address}
81}
82
83func (c *wrappedConn) SetDeadline(t time.Time) error {
84 panic("SetDeadline not implemented.")
85}
86
87func (c *wrappedConn) SetReadDeadline(t time.Time) error {
88 panic("SetReadDeadline not implemented.")
89}
90
91func (c *wrappedConn) SetWriteDeadline(t time.Time) error {
92 panic("SetWriteDeadline not implemented.")
93}
94
95type websocketAddr struct {
96 s string
97}
98
99func (websocketAddr) Network() string {
100 return "ws"
101}
102
103func (w websocketAddr) String() string {
104 return w.s
105}