Update message format for test js stuff
This commit is contained in:
parent
77b0e51691
commit
0de2509d2e
3 changed files with 114 additions and 55 deletions
|
@ -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};
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
Loading…
Reference in a new issue