- DIMP - https://github.com/dimchat/core-js/blob/master/DIMP/dist/dimp.js
- SDK - https://github.com/dimchat/sdk-js/blob/master/SDK/dist/sdk.js
Patches:
All in one - https://github.com/dimchat/sdk-js/blob/master/SDK/dist/all.js
User private key, ID, meta, and profile are generated in client,
and broadcast only meta
& profile
onto DIM station.
Step 1. generate private key (with asymmetric algorithm)
var PrivateKey = DIMP.crypto.PrivateKey;
var sk = PrivateKey.generate(PrivateKey.RSA);
NOTICE: After registered, the client should save the private key in secret storage.
Step 2. generate meta with private key (and meta seed)
var MetaType = DIMP.protocol.MetaType;
var Meta = DIMP.Meta;
var seed = "username";
var meta = Meta.generate(MetaType.Default, sk, seed);
Step 3. generate ID with meta (and network type)
var NetworkType = DIMP.protocol.NetworkType;
var identifier = meta.generateIdentifier(NetworkType.Main);
Step 4. create profile with ID and sign with private key
var Profile = DIMP.Profile;
var profile = new Profile(identifier);
// set nickname and avatar URL
profile.setName("Albert Moky");
profile.setProperty("avatar", "https://secure.gravatar.com/avatar/34aa0026f924d017dcc7a771f495c086");
// sign
profile.sign(privateKey);
Step 5. send meta & profile to station
var ProfileCommand = DIMP.protocol.ProfileCommand;
var messenger = Messenger.getInstance();
var cmd = ProfileCommand.response(identifier, profile, meta);
messenger.sendCommand(cmd);
The profile should be sent to station after connected and handshake accepted, details are provided in later chapters
Step 1. connect to DIM station (TCP)
Step 2. prepare for receiving message data package
var onReceive = function (responseData) {
var response = messenger.onReceivePackage(responseData);
if (response != null && response.length > 0) {
// send processing result back to the station
send(response);
}
}
Step 3. send first handshake command
(1) create handshake command
var HandshakeCommand = DIMP.protocol.HandshakeCommand;
// first handshake will have no session key
var cmd = HandshakeCommand.start();
(2) pack, encrypt and sign
var Envelope = DIMP.Envelope;
var InstantMessage = DIMP.InstantMessage;
var env = Envelope.newEnvelope(userId, stationId);
var iMsg = InstantMessage.newMessage(cmd, env);
var sMsg = messenger.encryptMessage(iMsg);
var rMsg = messenger.signMessage(sMsg);
(3) Meta protocol
Attaching meta in the first message package is to make sure the station can find it, particularly when it's first time the user connect to this station.
rMsg.setMeta(user.getMeta());
(4) send out serialized message data package
var data = messenger.serializeMessage(rMsg);
send(data);
Step 4. waiting handshake response
The CPU (Command Processing Units) will catch the handshake command response from station, and CPU will process them automatically, so just wait untill handshake success or network error.
- Text message
var TextContent = DIMP.protocol.TextContent;
var content = new TextContent("Hey, girl!");
NOTICE: file message content (Image, Audio, Video) will be sent out only includes the filename and a URL where the file data (encrypted with the same symmetric key) be stored.
- Query meta with contact ID
var MetaCommand = DIMP.protocol.MetaCommand;
var cmd = new MetaCommand(identifier);
- Query profile with contact ID
var ProfileCommand = DIMP.protocol.ProfileCommand;
var cmd = new ProfileCommand(identifier);
/**
* Pack and send command to station
*
* @param cmd - command
* @return true on success
*/
Messenger.prototype.sendCommand(Command cmd) {
console.assert(server !== null, 'station not connect');
return this.sendContent(cmd, server.identifier);
}
MetaCommand or ProfileCommand with only ID means querying, and the CPUs will catch and process all the response automatically.
You can send a customized command (such as search command) and prepare a processor to handle the response.
var CommandProcessor = DIMP.cpu.CommandProcessor;
/**
* Search Command Processor
*/
var SearchCommandProcessor = function (messenger) {
CommandProcessor.call(this, messenger);
};
SearchCommandProcessor.inherits(CommandProcessor);
//
// Main
//
SearchCommandProcessor.prototype.process = function (cmd, sender, msg) {
// TODO:
};
/**
* Handshake Command Processor
*/
var HandshakeCommandProcessor = function (messenger) {
CommandProcessor.call(this, messenger);
};
HandshakeCommandProcessor.inherits(CommandProcessor);
var success = function () {
var session = this.getContext('session_key');
var server = this.messenger.server;
server.handshakeAccepted(session, true);
return null;
};
var restart = function (session) {
this.setContext('session_key', session);
return new HandshakeCommand.restart(session)
};
//
// Main
//
HandshakeCommandProcessor.prototype.process = function (cmd, sender, msg) {
var message = cmd.getMessage();
if (message === 'DIM!' || message === 'OK!') {
// S -> C
return success.call(this);
} else if (message === 'DIM?') {
// S -> C
return restart.call(this, cmd.getSessionKey());
} else {
// C -> S: Hello world!
throw Error('handshake command error: ' + cmd);
}
};
And don't forget to register them.
CommandProcessor.register(Command.HANDSHAKE, HandshakeCommandProcessor);
CommandProcessor.register(SearchCommand.SEARCH, SearchCommandProcessor);
CommandProcessor.register(SearchCommand.ONLINE_USERS, SearchCommandProcessor);
Copyright © 2019 Albert Moky