Skip to content

dimchat/sdk-dart

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Decentralized Instant Messaging (Dart SDK)

License PRs Welcome Platform Issues Repo Size Tags Version

Watchers Forks Stars Followers

Dependencies

  • Latest Versions
Name Version Description
Ming Ke Ming (名可名) Version Decentralized User Identity Authentication
Dao Ke Dao (道可道) Version Universal Message Module
DIMP (去中心化通讯协议) Version Decentralized Instant Messaging Protocol

Extensions

Content

extends CustomizedContent

ContentProcessor

import 'package:dimsdk/dimsdk.dart';


///  Customized Content Processing Unit
///  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
///  Handle content for application customized
class AppCustomizedProcessor extends CustomizedContentProcessor {
  AppCustomizedProcessor(super.facebook, super.messenger);

  final Map<String, CustomizedContentHandler> _handlers = {};

  void setHandler({
    required String app, required String mod,
    required CustomizedContentHandler handler
  }) => _handlers['$app:$mod'] = handler;

  // protected
  CustomizedContentHandler? getHandler({
    required String app, required String mod,
  }) => _handlers['$app:$mod'];

  /// override for your modules
  @override
  CustomizedContentHandler filter(String app, String mod, CustomizedContent content, ReliableMessage rMsg) {
    CustomizedContentHandler? handler = getHandler(app: app, mod: mod);
    if (handler != null) {
      return handler;
    }
    // default handler
    return super.filter(app, mod, content, rMsg);
  }

}
import 'package:dimsdk/dimsdk.dart';

import '../../common/protocol/groups.dart';


/*  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             |
    +===============================+===============================+
 */
class GroupHistoryHandler extends BaseCustomizedHandler {
  GroupHistoryHandler(super.facebook, super.messenger);

  @override
  Future<List<Content>> handleAction(String act, ID sender, CustomizedContent content, ReliableMessage rMsg) async {
    if (content.group == null) {
      assert(false, 'group command error: $content, sender: $sender');
      String text = 'Group command error.';
      return respondReceipt(text, envelope: rMsg.envelope, content: content);
    } else if (GroupHistory.ACT_QUERY == act) {
      assert(GroupHistory.APP == content.application);
      assert(GroupHistory.MOD == content.module);
      return await transformQueryCommand(content, rMsg);
    }
    assert(false, 'unknown action: $act, $content, sender: $sender');
    return await super.handleAction(act, sender, content, rMsg);
  }

  // private
  Future<List<Content>> transformQueryCommand(CustomizedContent content, ReliableMessage rMsg) async {
    var transceiver = messenger;
    if (transceiver == null) {
      assert(false, 'messenger lost');
      return [];
    }
    Map info = content.copyMap(false);
    info['type'] = ContentType.COMMAND;
    info['command'] = GroupCommand.QUERY;
    Content? query = Content.parse(info);
    if (query is QueryCommand) {
      return await transceiver.processContent(query, rMsg);
    }
    assert(false, 'query command error: $query, $content, sender: ${rMsg.sender}');
    String text = 'Query command error.';
    return respondReceipt(text, envelope: rMsg.envelope, content: content);
  }

}

ContentProcessorCreator

import 'package:dimsdk/dimsdk.dart';

import 'customized.dart';
import 'handshake.dart';


class ClientContentProcessorCreator extends BaseContentProcessorCreator {
  ClientContentProcessorCreator(super.facebook, super.messenger);

  // protected
  AppCustomizedProcessor createCustomizedContentProcessor(Facebook facebook, Messenger messenger) {
    var cpu = AppCustomizedProcessor(facebook, messenger);
    
    // 'chat.dim.group:history'
    cpu.setHandler(
      app: GroupHistory.APP,
      mod: GroupHistory.MOD,
      handler: GroupHistoryHandler(facebook, messenger),
    );
    
    return cpu;
  }

  @override
  ContentProcessor? createContentProcessor(String msgType) {
    switch (msgType) {

      // application customized
      case ContentType.APPLICATION:
      case 'application':
      case ContentType.CUSTOMIZED:
      case 'customized':
        return createCustomizedContentProcessor(facebook!, messenger!);

      // ...
    }
    // others
    return super.createContentProcessor(msgType);
  }

  @override
  ContentProcessor? createCommandProcessor(String msgType, String cmd) {
    switch (cmd) {
    
      case HandshakeCommand.HANDSHAKE:
        return HandshakeCommandProcessor(facebook!, messenger!);
        
      // ...
    }
    // others
    return super.createCommandProcessor(msgType, cmd);
  }

}

Usage

To let your AppCustomizedProcessor start to work, you must override BaseContentProcessorCreator for message types:

  1. ContentType.APPLICATION
  2. ContentType.CUSTOMIZED

and then set your creator for GeneralContentProcessorFactory in the MessageProcessor.


Copyright © 2023-2025 Albert Moky Followers

About

Decentralized Instant Messaging (Dart SDK)

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages