Decentralized Instant Messaging Protocol (Java)
Handshake Command Protocol
0. (C-S) handshake start
(S-C) handshake again with new session
(C-S) handshake restart with new session
(S-C) handshake success
public enum HandshakeState {
START , // C -> S, without session key(or session expired)
AGAIN , // S -> C, with new session key
RESTART , // C -> S, with new session key
SUCCESS ; // S -> C, handshake accepted
public static HandshakeState checkState (String title , String session ) {
assert title != null : "handshake title should not be empty" ;
if (title .equals ("DIM!" )/* || text.equals("OK!")*/ ) {
return SUCCESS ;
} else if (title .equals ("DIM?" )) {
return AGAIN ;
} else if (session == null ) {
return START ;
} else {
return RESTART ;
}
}
}
/**
* Handshake command message
*
* <blockquote><pre>
* data format: {
* type : 0x88,
* sn : 123,
*
* command : "handshake", // command name
* title : "Hello world!", // "DIM?", "DIM!"
* session : "{SESSION_KEY}" // session key
* }
* </pre></blockquote>
*/
public interface HandshakeCommand extends Command {
String HANDSHAKE = "handshake" ;
String getTitle ();
String getSessionKey ();
HandshakeState getState ();
static HandshakeCommand start () {
return new BaseHandshakeCommand ("Hello world!" , null );
}
static HandshakeCommand restart (String sessionKey ) {
return new BaseHandshakeCommand ("Hello world!" , sessionKey );
}
static HandshakeCommand again (String sessionKey ) {
return new BaseHandshakeCommand ("DIM?" , sessionKey );
}
static HandshakeCommand success (String sessionKey ) {
return new BaseHandshakeCommand ("DIM!" , sessionKey );
}
}
public class BaseHandshakeCommand extends BaseCommand implements HandshakeCommand {
public BaseHandshakeCommand (Map <String , Object > content ) {
super (content );
}
public BaseHandshakeCommand (String text , String session ) {
super (HANDSHAKE );
// text message
assert text != null : "new handshake command error" ;
put ("title" , text );
// session key
if (session != null ) {
put ("session" , session );
}
}
@ Override
public String getTitle () {
return getString ("title" , null );
}
@ Override
public String getSessionKey () {
return getString ("session" , null );
}
@ Override
public HandshakeState getState () {
return HandshakeState .checkState (getTitle (), getSessionKey ());
}
}
/**
* Content for Application 0nly
*
* <blockquote><pre>
* data format: {
* "type" : i2s(0xA0),
* "sn" : 123,
*
* "app" : "{APP_ID}", // application (e.g.: "chat.dim.sechat")
* "extra" : info // others
* }
* </pre></blockquote>
*/
public interface AppContent extends Content {
// get App ID
String getApplication ();
}
/**
* Customized Content
*
* <blockquote><pre>
* data format: {
* "type" : i2s(0xCC),
* "sn" : 123,
*
* "app" : "{APP_ID}", // application (e.g.: "chat.dim.sechat")
* "mod" : "{MODULE}", // module name (e.g.: "drift_bottle")
* "act" : "{ACTION}", // action name (3.g.: "throw")
* "extra" : info // action parameters
* }
* </pre></blockquote>
*/
public interface CustomizedContent extends Content {
// get Module Name
String getModule ();
// get Action Name
String getAction ();
//
// Factory methods
//
static CustomizedContent create (String app , String mod , String act ) {
return new AppCustomizedContent (app , mod , act );
}
static CustomizedContent create (String type , String app , String mod , String act ) {
return new AppCustomizedContent (type , app , mod , act );
}
}
public class AppCustomizedContent extends BaseContent implements AppContent , CustomizedContent {
public AppCustomizedContent (Map <String , Object > content ) {
super (content );
}
public AppCustomizedContent (String type , String app , String mod , String act ) {
super (type );
put ("app" , app );
put ("mod" , mod );
put ("act" , act );
}
public AppCustomizedContent (String app , String mod , String act ) {
super (ContentType .CUSTOMIZED );
put ("app" , app );
put ("mod" , mod );
put ("act" , act );
}
//-------- getters --------
@ Override
public String getApplication () {
return getString ("app" , "" );
}
@ Override
public String getModule () {
return getString ("mod" , "" );
}
@ Override
public String getAction () {
return getString ("act" , "" );
}
}
Copyright © 2018-2026 Albert Moky