/
message-io.coffee
91 lines (69 loc) · 2.64 KB
/
message-io.coffee
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
require('./buffertools')
EventEmitter = require('events').EventEmitter
isPacketComplete = require('./packet').isPacketComplete
packetLength = require('./packet').packetLength
packetHeaderLength = require('./packet').HEADER_LENGTH
Packet = require('./packet').Packet
class MessageIO extends EventEmitter
constructor: (@socket, @_packetSize, @debug) ->
@socket.addListener('data', @eventData)
@packetDataSize = @_packetSize - packetHeaderLength
@packetBuffer = new Buffer(0)
@payloadBuffer = new Buffer(0)
eventData: (data) =>
if (@packetBuffer.length > 0)
@packetBuffer = Buffer.concat([@packetBuffer, data])
else
@packetBuffer = data
packetsData = []
endOfMessage = false
while isPacketComplete(@packetBuffer)
length = packetLength(@packetBuffer)
packet = new Packet(@packetBuffer.slice(0, length))
@logPacket('Received', packet);
packetsData.push(packet.data())
if (packet.isLast())
endOfMessage = true
@packetBuffer = @packetBuffer.slice(length)
if packetsData.length > 0
@emit('data', Buffer.concat(packetsData))
if endOfMessage
@emit('message')
packetSize: (packetSize) ->
if arguments.length > 0
@debug.log("Packet size changed from #{@_packetSize} to #{packetSize}")
@_packetSize = packetSize
@packetDataSize = @_packetSize - packetHeaderLength
@_packetSize
encryptAllFutureTraffic: (securePair) ->
@securePair = securePair
@socket.removeAllListeners('data')
@securePair.encrypted.removeAllListeners('data')
@socket.pipe(@securePair.encrypted)
@securePair.encrypted.pipe(@socket)
@securePair.cleartext.addListener('data', @eventData)
# TODO listen for 'drain' event when socket.write returns false.
sendMessage: (packetType, data) ->
numberOfPackets = (Math.floor((data.length - 1) / @packetDataSize)) + 1
for packetNumber in [0..numberOfPackets - 1]
payloadStart = packetNumber * @packetDataSize
if packetNumber < numberOfPackets - 1
payloadEnd = payloadStart + @packetDataSize
else
payloadEnd = data.length
packetPayload = data.slice(payloadStart, payloadEnd)
packet = new Packet(packetType)
packet.last(packetNumber == numberOfPackets - 1)
packet.packetId(packetNumber + 1)
packet.addData(packetPayload)
@sendPacket(packet)
sendPacket: (packet) =>
@logPacket('Sent', packet);
if (@securePair)
@securePair.cleartext.write(packet.buffer)
else
@socket.write(packet.buffer)
logPacket: (direction, packet) ->
@debug.packet(direction, packet)
@debug.data(packet)
module.exports = MessageIO