Update message format for test js stuff

This commit is contained in:
Chris Marsh 2017-07-07 16:00:29 -07:00
parent 77b0e51691
commit 0de2509d2e
3 changed files with 114 additions and 55 deletions

View file

@ -1,22 +1,61 @@
const path = require('path');
module.exports = class RpcMessage { const VERSION = 1;
static serialize(obj) {
const OPCODES = {
HANDSHAKE: 0,
FRAME: 1,
CLOSE: 2,
};
let PipePath;
if (process.platform == 'win32') {
PipePath = '\\\\?\\pipe\\discord-ipc';
}
else {
const temp = process.env.XDG_RUNTIME_DIR || process.env.TMPDIR || process.env.TMP || process.env.TEMP || '/tmp';
PipePath = path.join(temp, 'discord-ipc');
}
class RpcMessage {
static serialize(opcode, obj) {
const serializedJson = JSON.stringify(obj); const serializedJson = JSON.stringify(obj);
const msgLen = 4 + serializedJson.length; const msgLen = serializedJson.length;
let buff = Buffer.alloc(msgLen); let buff = Buffer.alloc(8 + msgLen);
buff.writeInt32LE(msgLen, 0); buff.writeInt32LE(opcode, 0);
buff.write(serializedJson, 4, serializedJson.length, 'utf-8'); buff.writeInt32LE(msgLen, 4);
buff.write(serializedJson, 8, serializedJson.length, 'utf-8');
return buff; return buff;
} }
static handshake(id) {
const opcode = OPCODES.HANDSHAKE;
return RpcMessage.serialize(opcode, {
client_id: id,
v: VERSION
});
}
static send(obj) {
const opcode = OPCODES.FRAME;
return RpcMessage.serialize(opcode, obj);
}
static sendClose(code, message) {
const opcode = OPCODES.CLOSE;
return RpcMessage.serialize(opcode, {code, message});
}
static deserialize(buff) { static deserialize(buff) {
const msgLen = buff.readInt32LE(0); const opcode = buff.readInt32LE(0);
if (buff.length < msgLen) { const msgLen = buff.readInt32LE(4);
if (buff.length < (msgLen + 8)) {
return null; return null;
} }
const msg = buff.toString('utf-8', 4, msgLen); const msg = buff.toString('utf-8', 8, msgLen + 8);
try { try {
return JSON.parse(msg); return {opcode, data: JSON.parse(msg)};
} catch(e) { } catch(e) {
console.log(`failed to parse "${msg}"`); console.log(`failed to parse "${msg}"`);
console.error(e); console.error(e);
@ -24,3 +63,5 @@ module.exports = class RpcMessage {
} }
} }
}; };
module.exports = {OPCODES, PipePath, RpcMessage};

View file

@ -1,48 +1,59 @@
const net = require('net'); const net = require('net');
const RpcMessage = require('./rpc-message'); const repl = require('repl');
const {PipePath, RpcMessage} = require('./rpc-message');
let PipePrefix; let connectionNonce = 0;
let PipePostfix; global.connections = {};
if (process.platform == 'win32') {
PipePrefix = '\\\\.\\pipe\\';
PipePostfix = '';
}
else {
PipePrefix = "/tmp";
PipePostfix = '.pipe';
}
const PipePath = PipePrefix + 'DiscordRpcServer' + PipePostfix;
let connections = 0;
const server = net.createServer(function(sock) { const server = net.createServer(function(sock) {
connections += 1; connectionNonce += 1;
console.log('Server: on connection', connections); console.log('Server: on connection', connectionNonce);
let myConnection = connections; let myConnection = connectionNonce;
let messages = 0;
global.connections[myConnection] = sock;
sock.on('data', function(data) { sock.on('data', function(data) {
messages++;
const msgObj = RpcMessage.deserialize(data); const msgObj = RpcMessage.deserialize(data);
if (msgObj != null) { if (msgObj != null) {
console.log('Server: on data:', myConnection, msgObj); const {opcode, data} = msgObj;
console.log(`\nServer (${myConnection}): got opcode: ${opcode}, data: ${JSON.stringify(data)}`);
} }
else { else {
console.log('Server: got some data', data.toString()); console.log('\nServer: got some data', data.toString());
} }
}); });
sock.on('end', function() { sock.on('end', function() {
connections -= 1; delete global.connections[myConnection];
console.log('Server: on end', connections); console.log('\nServer: on end', myConnection);
}); });
}); });
server.on('close', function(){ server.on('close', function(){
console.log('Server: on close'); console.log('\nServer: on close');
}) });
try { try {
server.listen(PipePath, function(){ server.listen(PipePath, function(){
console.log('Server: on listening'); console.log('\nServer: on listening');
}); });
} catch(e) { } catch(e) {
console.error('could not start server:', e); console.error('\nServer: could not start:', e);
} }
const replServer = repl.start({prompt: '> ', useGlobal: true, breakEvalOnSigint: true});
replServer.defineCommand('kill', {
help: 'Kill a client',
action(who) {
this.bufferedCommand = '';
who = parseInt(who, 10);
const sock = global.connections[who];
if (sock) {
sock.write(RpcMessage.sendClose(123, 'killed'));
sock.end();
}
this.displayPrompt();
}
});

View file

@ -1,32 +1,27 @@
const net = require('net'); const net = require('net');
const RpcMessage = require('./rpc-message'); const {OPCODES, PipePath, RpcMessage} = require('./rpc-message');
let PipePrefix; const APP_ID = '12345678910';
let PipePostfix; global.isConnected = false;
if (process.platform == 'win32') { global.timeoutId = null;
PipePrefix = '\\\\.\\pipe\\';
PipePostfix = '';
}
else {
PipePrefix = "/tmp";
PipePostfix = '.pipe';
}
const PipePath = PipePrefix + "DiscordRpcServer" + PipePostfix;
function sendMesg(testUpdatesToSend, stream) { function sendMesg(testUpdatesToSend, stream) {
const msgObj = { const msgObj = {
name: 'My Awesome Game', state: (testUpdatesToSend % 2 == 0) ? 'In a match' : 'In Lobby',
state: (testUpdatesToSend % 2 == 0) ? 'In a match' : 'In Lobby' details: 'Excited'
}; };
console.log('Client: send update:', msgObj); console.log('Client: send update:', msgObj);
stream.write(RpcMessage.serialize(msgObj)); stream.write(RpcMessage.send(msgObj));
} }
function sendMessageLoop(testUpdatesToSend, interval, stream) { function sendMessageLoop(testUpdatesToSend, interval, stream) {
global.timeoutId = null;
if (!global.isConnected) {
return;
}
sendMesg(testUpdatesToSend, stream); sendMesg(testUpdatesToSend, stream);
if (testUpdatesToSend > 1) { if (testUpdatesToSend > 1) {
setTimeout(() => {sendMessageLoop(testUpdatesToSend - 1, interval, stream)}, interval); global.timeoutId = setTimeout(() => {sendMessageLoop(testUpdatesToSend - 1, interval, stream)}, interval);
} else { } else {
shutdown(); shutdown();
} }
@ -34,23 +29,35 @@ function sendMessageLoop(testUpdatesToSend, interval, stream) {
const client = net.connect(PipePath, function(stream) { const client = net.connect(PipePath, function(stream) {
console.log('Client: on connection'); console.log('Client: on connection');
global.isConnected = true;
sendMessageLoop(5, 3000, client); client.write(RpcMessage.handshake(APP_ID));
sendMessageLoop(10, 3000, client);
}); });
client.on('data', function(data) { client.on('data', function(data) {
const msgObj = RpcMessage.deserialize(data); const msgObj = RpcMessage.deserialize(data);
if (msgObj != null) { if (msgObj != null) {
console.log('Client: got data:', msgObj); const {opcode, data} = msgObj;
console.log(`Client: got opcode: ${opcode}, data: ${JSON.stringify(data)}`);
if (opcode == OPCODES.CLOSE) {
shutdown();
}
} else { } else {
console.log('Client: got some data'); console.log('Client: got some data', data);
} }
}); });
client.on('end', function() { client.on('end', function() {
global.isConnected = false;
console.log('Client: on end'); console.log('Client: on end');
}); });
function shutdown() { function shutdown() {
if (global.timeoutId !== null) {
clearTimeout(global.timeoutId);
global.timeoutId = null;
}
client.end(); client.end();
} }