1 | defaultAdapter =
|
2 | users: {}
|
3 | register: (req, cb) ->
|
4 | @users[req.name] = req.socket.id
|
5 | cb()
|
6 |
|
7 | getId: (name, cb) ->
|
8 | cb @users[name]
|
9 |
|
10 | unregister: (req, cb) ->
|
11 | delete @users[req.name]
|
12 | cb()
|
13 |
|
14 | getPresenceTargets: (req, cb) ->
|
15 | cb (id for user, id of @users when user isnt req.name)
|
16 |
|
17 | module.exports =
|
18 | options:
|
19 | namespace: 'holla'
|
20 | resource: 'default'
|
21 | presence: true
|
22 | debug: false
|
23 |
|
24 | start: ->
|
25 | @adapter = {}
|
26 | for k,v of defaultAdapter
|
27 | if typeof v is "function"
|
28 | @adapter[k]=v.bind @adapter
|
29 | else
|
30 | @adapter[k]=v
|
31 |
|
32 | if @options.adapter
|
33 | for k,v of @options.adapter
|
34 | if typeof v is "function"
|
35 | @adapter[k]=v.bind @adapter
|
36 | else
|
37 | @adapter[k]=v
|
38 |
|
39 | if @options.presence
|
40 | @on 'register', (req) =>
|
41 | @updatePresence
|
42 | name: req.socket.identity
|
43 | socket: req.socket
|
44 | online: true
|
45 |
|
46 | @on 'unregister', (req) =>
|
47 | @updatePresence
|
48 | name: req.socket.identity
|
49 | socket: req.socket
|
50 | online: false
|
51 |
|
52 | updatePresence: (preq) ->
|
53 | @adapter.getPresenceTargets preq, (sockets) =>
|
54 | for id in sockets
|
55 | @server.clients[id]?.write
|
56 | type: "presence"
|
57 | args:
|
58 | name: preq.name
|
59 | online: preq.online
|
60 | return
|
61 |
|
62 | validate: (socket, msg, done) ->
|
63 | if @options.debug
|
64 | console.log socket.id, socket.identity, msg
|
65 | return done false unless typeof msg is 'object'
|
66 | return done false unless typeof msg.type is 'string'
|
67 | if msg.type is "register"
|
68 | return done false unless typeof msg.args is 'object'
|
69 | return done false unless typeof msg.args.name is 'string'
|
70 | else if msg.type is "offer"
|
71 | return done false unless typeof msg.to is 'string'
|
72 | return done false unless socket.identity
|
73 | else if msg.type is "hangup"
|
74 | return done false unless typeof msg.to is 'string'
|
75 | return done false unless socket.identity
|
76 | else if msg.type is "answer"
|
77 | return done false unless typeof msg.to is 'string'
|
78 | return done false unless socket.identity
|
79 | return done false unless typeof msg.args is 'object'
|
80 | return done false unless typeof msg.args.accepted is 'boolean'
|
81 | else if msg.type is "candidate"
|
82 | return done false unless typeof msg.to is 'string'
|
83 | return done false unless socket.identity
|
84 | return done false unless typeof msg.args is 'object'
|
85 | return done false unless typeof msg.args.candidate is 'object'
|
86 | else if msg.type is "sdp"
|
87 | return done false unless typeof msg.to is 'string'
|
88 | return done false unless socket.identity
|
89 | return done false unless typeof msg.args is 'object'
|
90 | return done false unless msg.args.sdp
|
91 | return done false unless msg.args.type
|
92 | else if msg.type is "chat"
|
93 | return done false unless typeof msg.to is 'string'
|
94 | return done false unless socket.identity
|
95 | return done false unless typeof msg.args is 'object'
|
96 | return done false unless typeof msg.args.message is 'string'
|
97 | else
|
98 | return done false
|
99 | return done true
|
100 |
|
101 | close: (socket, reason) ->
|
102 | req =
|
103 | name: socket.identity
|
104 | reason: reason
|
105 | socket: socket
|
106 |
|
107 | @emit "close", req
|
108 | @adapter.unregister req, =>
|
109 | @emit "unregister", req
|
110 |
|
111 | invalid: (socket, msg) -> socket.close()
|
112 | error: (socket, msg) -> socket.close()
|
113 |
|
114 | message: (socket, msg) ->
|
115 | switch msg.type
|
116 | when "register"
|
117 | req =
|
118 | name: msg.args.name
|
119 | socket: socket
|
120 | @adapter.register req, (err) =>
|
121 | unless err?
|
122 | socket.identity ?= msg.args.name
|
123 | @emit "register", req
|
124 | socket.write
|
125 | type: "register"
|
126 | args:
|
127 | result: !err
|
128 |
|
129 | when "offer"
|
130 | @adapter.getId msg.to, (id) =>
|
131 | return unless @server.clients[id]?
|
132 | @server.clients[id].write
|
133 | type: "offer"
|
134 | from: socket.identity
|
135 |
|
136 | req =
|
137 | name: socket.identity
|
138 | socket: socket
|
139 | to: msg.to
|
140 |
|
141 | @emit "offer", req
|
142 |
|
143 | when "hangup"
|
144 | @adapter.getId msg.to, (id) =>
|
145 | return unless @server.clients[id]?
|
146 | @server.clients[id].write
|
147 | type: "hangup"
|
148 | from: socket.identity
|
149 |
|
150 | req =
|
151 | name: socket.identity
|
152 | socket: socket
|
153 | to: msg.to
|
154 |
|
155 | @emit "hangup", req
|
156 |
|
157 | when "answer"
|
158 | @adapter.getId msg.to, (id) =>
|
159 | return unless @server.clients[id]?
|
160 | @server.clients[id].write
|
161 | type: "answer"
|
162 | from: socket.identity
|
163 | args:
|
164 | accepted: msg.args.accepted
|
165 |
|
166 | req =
|
167 | name: socket.identity
|
168 | socket: socket
|
169 | to: msg.to
|
170 | args:
|
171 | accepted: msg.args.accepted
|
172 |
|
173 | @emit "answer", req
|
174 |
|
175 | when "candidate"
|
176 | @adapter.getId msg.to, (id) =>
|
177 | return unless @server.clients[id]?
|
178 | @server.clients[id].write
|
179 | type: "candidate"
|
180 | from: socket.identity
|
181 | args:
|
182 | candidate: msg.args.candidate
|
183 |
|
184 | when "sdp"
|
185 | @adapter.getId msg.to, (id) =>
|
186 | return unless @server.clients[id]?
|
187 | @server.clients[id].write
|
188 | type: "sdp"
|
189 | from: socket.identity
|
190 | args:
|
191 | sdp: msg.args.sdp
|
192 | type: msg.args.type
|
193 |
|
194 | when "chat"
|
195 | @adapter.getId msg.to, (id) =>
|
196 | return unless @server.clients[id]?
|
197 | @server.clients[id].write
|
198 | type: "chat"
|
199 | from: socket.identity
|
200 | args:
|
201 | message: msg.args.message
|
202 |
|
203 | req =
|
204 | name: socket.identity
|
205 | socket: socket
|
206 | to: msg.to
|
207 | message: msg.args.message
|
208 |
|
209 | @emit "chat", req |
\ | No newline at end of file |