- Latest Versions
Name | Version | Description |
---|---|---|
Ming Ke Ming (名可名) | Decentralized User Identity Authentication | |
Dao Ke Dao (道可道) | Universal Message Module | |
DIMP (去中心化通讯协议) | Decentralized Instant Messaging Protocol |
- build.gradle
allprojects {
repositories {
jcenter()
mavenCentral()
}
}
dependencies {
// https://central.sonatype.com/artifact/chat.dim/SDK
implementation group: 'chat.dim', name: 'SDK', version: '2.0.0'
}
- pom.xml
<dependencies>
<!-- https://mvnrepository.com/artifact/chat.dim/SDK -->
<dependency>
<groupId>chat.dim</groupId>
<artifactId>SDK</artifactId>
<version>2.0.0</version>
<type>pom</type>
</dependency>
</dependencies>
extends CustomizedContent
import java.util.HashMap;
import java.util.Map;
import chat.dim.Facebook;
import chat.dim.Messenger;
import chat.dim.cpu.app.CustomizedContentHandler;
import chat.dim.protocol.CustomizedContent;
import chat.dim.protocol.ReliableMessage;
/**
* Customized Content Processing Unit
* <p>
* Handle content for application customized
* </p>
*/
public class AppCustomizedProcessor extends CustomizedContentProcessor {
private final Map<String, CustomizedContentHandler> handlers = new HashMap<>();
public AppCustomizedProcessor(Facebook facebook, Messenger messenger) {
super(facebook, messenger);
}
public void setHandler(String app, String mod, CustomizedContentHandler handler) {
handlers.put(app + ":" + mod, handler);
}
protected CustomizedContentHandler getHandler(String app, String mod) {
return handlers.get(app + ":" + mod);
}
@Override
protected CustomizedContentHandler filter(String app, String mod, CustomizedContent content, ReliableMessage rMsg) {
CustomizedContentHandler handler = getHandler(app, mod);
if (handler != null) {
return handler;
}
// default handler
return super.filter(app, mod, content, rMsg);
}
}
import java.util.List;
import java.util.Map;
import chat.dim.Facebook;
import chat.dim.Messenger;
import chat.dim.protocol.*;
import chat.dim.protocol.group.*;
/* Command Transform:
+===============================+===============================+
| Customized Content | Group Query Command |
+-------------------------------+-------------------------------+
| "type" : i2s(0xCC) | "type" : i2s(0x88) |
| "sn" : 123 | "sn" : 123 |
| "time" : 123.456 | "time" : 123.456 |
| "app" : "chat.dim.group" | |
| "mod" : "history" | |
| "act" : "query" | |
| | "command" : "query" |
| "group" : "{GROUP_ID}" | "group" : "{GROUP_ID}" |
| "last_time" : 0 | "last_time" : 0 |
+===============================+===============================+
*/
public final class GroupHistoryHandler extends BaseCustomizedHandler {
public GroupHistoryHandler(Facebook facebook, Messenger messenger) {
super(facebook, messenger);
}
@Override
public List<Content> handleAction(String act, ID sender, CustomizedContent content, ReliableMessage rMsg) {
if (content.getGroup() == null) {
assert false : "group command error: " + content + ", sender: " + sender;
return respondReceipt("Group command error.", rMsg.getEnvelope(), content, null);
}
if (GroupHistory.ACT_QUERY.equals(act)) {
assert GroupHistory.APP.equals(content.getApplication());
assert GroupHistory.MOD.equals(content.getModule());
return transformQueryCommand(content, rMsg);
}
assert false : "unknown action: " + act + ", " + content + ", sender: " + sender;
return super.handleAction(act, sender, content, rMsg);
}
private List<Content> transformQueryCommand(CustomizedContent content, ReliableMessage rMsg) {
Messenger messenger = getMessenger();
if (messenger == null) {
assert false : "messenger lost";
return null;
}
Map<String, Object> info = content.copyMap(false);
info.put("type", ContentType.COMMAND);
info.put("command", GroupCommand.QUERY);
Content query = Content.parse(info);
if (query instanceof QueryCommand) {
return messenger.processContent(query, rMsg);
}
assert false : "query command error: " + query + ", " + content + ", sender: " + rMsg.getSender();
return respondReceipt("Query command error.", rMsg.getEnvelope(), content, null);
}
}
import chat.dim.Facebook;
import chat.dim.Messenger;
import chat.dim.cpu.app.GroupHistoryHandler;
import chat.dim.dkd.ContentProcessor;
import chat.dim.protocol.*;
import chat.dim.protocol.group.GroupHistory;
public class ClientContentProcessorCreator extends BaseContentProcessorCreator {
public ClientContentProcessorCreator(Facebook facebook, Messenger messenger) {
super(facebook, messenger);
}
protected AppCustomizedProcessor createCustomizedContentProcessor(Facebook facebook, Messenger messenger) {
AppCustomizedProcessor cpu = new AppCustomizedProcessor(facebook, messenger);
// 'chat.dim.group:history'
cpu.setHandler(
GroupHistory.APP,
GroupHistory.MOD,
new GroupHistoryHandler(facebook, messenger)
);
return cpu;
}
@Override
public ContentProcessor createContentProcessor(String msgType) {
switch (msgType) {
// application customized
case ContentType.APPLICATION:
case "application":
case ContentType.CUSTOMIZED:
case "customized":
return createCustomizedContentProcessor(getFacebook(), getMessenger());
// ...
}
// others
return super.createContentProcessor(msgType);
}
@Override
public ContentProcessor createCommandProcessor(String type, String name) {
switch (name) {
case HandshakeCommand.HANDSHAKE:
return new HandshakeCommandProcessor(getFacebook(), getMessenger());
// ...
}
// others
return super.createCommandProcessor(type, name);
}
}
import chat.dim.dkd.AppCustomizedContent;
import chat.dim.plugins.ExtensionLoader;
import chat.dim.protocol.*;
/**
* Extensions Loader
* ~~~~~~~~~~~~~~~~~
*/
public class CommonExtensionLoader extends ExtensionLoader {
@Override
protected void registerCustomizedFactories() {
// Application Customized
setContentFactory(ContentType.CUSTOMIZED, "customized", AppCustomizedContent::new);
setContentFactory(ContentType.APPLICATION, "application", AppCustomizedContent::new);
//super.registerCustomizedFactories();
}
/**
* Command factories
*/
@Override
protected void registerCommandFactories() {
super.registerCommandFactories();
// Handshake
setCommandFactory(HandshakeCommand.HANDSHAKE, HandshakeCommand::new);
}
}
You must load all extensions before your business run:
import chat.dim.plugins.ExtensionLoader;
import chat.dim.plugins.PluginLoader;
public class LibraryLoader implements Runnable {
private final ExtensionLoader extensionLoader;
private final PluginLoader pluginLoader;
public LibraryLoader(ExtensionLoader extensionLoader, PluginLoader pluginLoader) {
if (extensionLoader == null) {
this.extensionLoader = new CommonExtensionLoader();
} else {
this.extensionLoader = extensionLoader;
}
if (pluginLoader == null) {
this.pluginLoader = new PluginLoader();
} else {
this.pluginLoader = pluginLoader;
}
}
@Override
public void run() {
extensionLoader.run();
pluginLoader.run();
}
public static void main(String[] args) {
LibraryLoader loader = new LibraryLoader();
loader.run();
// do your jobs after all extensions loaded.
}
}
To let your AppCustomizedProcessor start to work,
you must override BaseContentProcessorCreator
for message types:
- ContentType.APPLICATION
- ContentType.CUSTOMIZED
and then set your creator for GeneralContentProcessorFactory
in the MessageProcessor
.