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 {
static serialize(obj) {
const VERSION = 1;
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 msgLen = 4 + serializedJson.length;
let buff = Buffer.alloc(msgLen);
buff.writeInt32LE(msgLen, 0);
buff.write(serializedJson, 4, serializedJson.length, 'utf-8');
const msgLen = serializedJson.length;
let buff = Buffer.alloc(8 + msgLen);
buff.writeInt32LE(opcode, 0);
buff.writeInt32LE(msgLen, 4);
buff.write(serializedJson, 8, serializedJson.length, 'utf-8');
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) {
const msgLen = buff.readInt32LE(0);
if (buff.length < msgLen) {
const opcode = buff.readInt32LE(0);
const msgLen = buff.readInt32LE(4);
if (buff.length < (msgLen + 8)) {
return null;
}
const msg = buff.toString('utf-8', 4, msgLen);
const msg = buff.toString('utf-8', 8, msgLen + 8);
try {
return JSON.parse(msg);
return {opcode, data: JSON.parse(msg)};
} catch(e) {
console.log(`failed to parse "${msg}"`);
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 RpcMessage = require('./rpc-message');
const repl = require('repl');
const {PipePath, RpcMessage} = require('./rpc-message');
let PipePrefix;
let PipePostfix;
if (process.platform == 'win32') {
PipePrefix = '\\\\.\\pipe\\';
PipePostfix = '';
}
else {
PipePrefix = "/tmp";
PipePostfix = '.pipe';
}
const PipePath = PipePrefix + 'DiscordRpcServer' + PipePostfix;
let connections = 0;
let connectionNonce = 0;
global.connections = {};
const server = net.createServer(function(sock) {
connections += 1;
console.log('Server: on connection', connections);
let myConnection = connections;
connectionNonce += 1;
console.log('Server: on connection', connectionNonce);
let myConnection = connectionNonce;
let messages = 0;
global.connections[myConnection] = sock;
sock.on('data', function(data) {
messages++;
const msgObj = RpcMessage.deserialize(data);
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 {
console.log('Server: got some data', data.toString());
console.log('\nServer: got some data', data.toString());
}
});
sock.on('end', function() {
connections -= 1;
console.log('Server: on end', connections);
delete global.connections[myConnection];
console.log('\nServer: on end', myConnection);
});
});
server.on('close', function(){
console.log('Server: on close');
})
console.log('\nServer: on close');
});
try {
server.listen(PipePath, function(){
console.log('Server: on listening');
console.log('\nServer: on listening');
});
} 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 RpcMessage = require('./rpc-message');
const {OPCODES, PipePath, RpcMessage} = require('./rpc-message');
let PipePrefix;
let PipePostfix;
if (process.platform == 'win32') {
PipePrefix = '\\\\.\\pipe\\';
PipePostfix = '';
}
else {
PipePrefix = "/tmp";
PipePostfix = '.pipe';
}
const PipePath = PipePrefix + "DiscordRpcServer" + PipePostfix;
const APP_ID = '12345678910';
global.isConnected = false;
global.timeoutId = null;
function sendMesg(testUpdatesToSend, stream) {
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);
stream.write(RpcMessage.serialize(msgObj));
stream.write(RpcMessage.send(msgObj));
}
function sendMessageLoop(testUpdatesToSend, interval, stream) {
global.timeoutId = null;
if (!global.isConnected) {
return;
}
sendMesg(testUpdatesToSend, stream);
if (testUpdatesToSend > 1) {
setTimeout(() => {sendMessageLoop(testUpdatesToSend - 1, interval, stream)}, interval);
global.timeoutId = setTimeout(() => {sendMessageLoop(testUpdatesToSend - 1, interval, stream)}, interval);
} else {
shutdown();
}
@ -34,23 +29,35 @@ function sendMessageLoop(testUpdatesToSend, interval, stream) {
const client = net.connect(PipePath, function(stream) {
console.log('Client: on connection');
sendMessageLoop(5, 3000, client);
global.isConnected = true;
client.write(RpcMessage.handshake(APP_ID));
sendMessageLoop(10, 3000, client);
});
client.on('data', function(data) {
const msgObj = RpcMessage.deserialize(data);
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 {
console.log('Client: got some data');
console.log('Client: got some data', data);
}
});
client.on('end', function() {
global.isConnected = false;
console.log('Client: on end');
});
function shutdown() {
if (global.timeoutId !== null) {
clearTimeout(global.timeoutId);
global.timeoutId = null;
}
client.end();
}