This repository has been archived by the owner on Apr 3, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathconn.go
121 lines (101 loc) · 2.36 KB
/
conn.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package dcnet
import (
"errors"
"fmt"
"io"
"net"
"time"
"github.com/pions/webrtc"
"github.com/pions/webrtc/pkg/datachannel"
)
// NewConn creates a Conn around a data channel. The data channel is assumed to be open already.
func NewConn(dc *webrtc.RTCDataChannel, laddr net.Addr, raddr net.Addr) (net.Conn, error) {
r, w := io.Pipe()
res := &Conn{
dc: dc,
laddr: laddr,
raddr: raddr,
p: r,
}
go func() {
dc.Lock()
defer dc.Unlock()
dc.Onmessage = func(payload datachannel.Payload) {
switch p := payload.(type) {
// case *datachannel.PayloadString:
// fmt.Printf("Message '%s' from DataChannel '%s' payload '%s'\n", p.PayloadType().String(), d.Label, string(p.Data))
case *datachannel.PayloadBinary:
w.Write(p.Data)
// default:
// fmt.Printf("Message '%s' from DataChannel '%s' no payload \n", p.PayloadType().String(), d.Label)
}
}
}()
return res, nil
}
// Conn is a net.Conn over a datachannel
type Conn struct {
dc *webrtc.RTCDataChannel
laddr net.Addr
raddr net.Addr
p *io.PipeReader
isClosed bool
}
// Read reads data from the underlying the data channel
func (c *Conn) Read(b []byte) (int, error) {
if c.isClosed {
return 0, errors.New("read on closed conn")
}
i, err := c.p.Read(b)
return i, err
}
// Write writes the data to the underlying data channel
func (c *Conn) Write(b []byte) (int, error) {
if c.isClosed {
return 0, errors.New("write on closed conn")
}
err := c.dc.Send(datachannel.PayloadBinary{Data: b})
if err != nil {
return 0, err
}
return len(b), nil
}
// Close closes the datachannel and peerconnection
func (c *Conn) Close() error {
if c.isClosed {
return errors.New("close on closed conn")
}
// TODO: Locking
c.isClosed = true
// Unblock readers
err := c.p.Close()
if err != nil {
fmt.Println("failed to close pipe:", err)
return err
}
// TODO: Implement datachannel closing procedure
// c.dc.Close()
// TODO: cleanup peerconnection
return nil
}
func (c *Conn) LocalAddr() net.Addr {
return c.laddr
}
func (c *Conn) RemoteAddr() net.Addr {
return c.raddr
}
// SetDeadline
func (c *Conn) SetDeadline(t time.Time) error {
panic("TODO")
return nil
}
// SetReadDeadline
func (c *Conn) SetReadDeadline(t time.Time) error {
panic("TODO")
return nil
}
// SetWriteDeadline
func (c *Conn) SetWriteDeadline(t time.Time) error {
panic("TODO")
return nil
}