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