Decentralized Instant Messaging Protocol (Python)
Dependencies
Examples
extends Command
- 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
from enum import IntEnum
from typing import Optional, Any, Dict
from dimp import Command, BaseCommand
class HandshakeState(IntEnum):
Start = 0
Again = 1
Restart = 2
Success = 3
class HandshakeCommand(BaseCommand):
"""
Handshake Command
~~~~~~~~~~~~~~~~~
data format: {
type : 0x88,
sn : 123,
command : "handshake", // command name
title : "Hello world!", // "DIM?", "DIM!"
session : "{SESSION_ID}", // session key
}
"""
HANDSHAKE = 'handshake'
def __init__(self, content: Dict[str, Any] = None, title: str = None, session: str = None):
if content is None:
assert title is not None, 'handshake command error: %s' % session
cmd = self.HANDSHAKE
super().__init__(cmd=cmd)
self['title'] = title
self['message'] = title
if session is not None:
self['session'] = session
else:
assert title is None and session is None, 'params error: %s, %s, %s' % (content, title, session)
super().__init__(content)
@property
def title(self) -> str:
text = self.get_str(key='title', default=None)
if text is None:
text = self.get_str(key='message', default='')
return text
@property
def session(self) -> Optional[str]:
return self.get_str(key='session', default=None)
@property
def state(self) -> HandshakeState:
return handshake_state(title=self.title, session=self.session)
@classmethod
def offer(cls, session: str = None) -> Command:
"""
Create client-station handshake offer
:param session: Old session key
:return: HandshakeCommand object
"""
return HandshakeCommand(title='Hello world!', session=session)
@classmethod
def ask(cls, session: str) -> Command:
"""
Create station-client handshake again with new session
:param session: New session key
:return: HandshakeCommand object
"""
return HandshakeCommand(title='DIM?', session=session)
@classmethod
def accepted(cls, session: str = None) -> Command:
"""
Create station-client handshake success notice
:return: HandshakeCommand object
"""
return HandshakeCommand(title='DIM!', session=session)
start = offer
again = ask
restart = offer
success = accepted
def handshake_state(title: str, session: str = None) -> HandshakeState:
if title == 'DIM!':
return HandshakeState.Success
if title == 'DIM?':
return HandshakeState.Again
if session is None or len(session) == 0:
return HandshakeState.Start
else:
return HandshakeState.Restart
extends Content
from abc import ABC, abstractmethod
from typing import Any, Dict
from dimp import ContentType
from dimp import Content
from dimp import BaseContent
class CustomizedContent(Content, ABC):
"""
Application Customized message
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
data format: {
type : 0xCC,
sn : 123,
app : "{APP_ID}", // application (e.g.: "chat.dim.sechat")
mod : "{MODULE}", // module name (e.g.: "drift_bottle")
act : "{ACTION}", // action name (e.g.: "throw")
extra : info // action parameters
}
"""
@property
@abstractmethod
def application(self) -> str:
""" App ID """
raise NotImplemented
@property
@abstractmethod
def module(self) -> str:
""" Module Name """
raise NotImplemented
@property
@abstractmethod
def action(self) -> str:
""" Action Name """
raise NotImplemented
@classmethod
def create(cls, app: str, mod: str, act: str):
return AppCustomizedContent(app=app, mod=mod, act=act)
class AppCustomizedContent(BaseContent, CustomizedContent):
def __init__(self, content: Dict[str, Any] = None,
msg_type: int = None,
app: str = None, mod: str = None, act: str = None):
if content is None:
assert app is not None and mod is not None and act is not None, \
'customized content error: %s, %s, %s, %s' % (msg_type, app, mod, act)
if msg_type is None:
msg_type = ContentType.CUSTOMIZED.value
super().__init__(None, msg_type)
self['app'] = app
self['mod'] = mod
self['act'] = act
else:
assert msg_type is None and app is None and mod is None and act is None, \
'params error: %s, %s, %s, %s, %s' % (content, msg_type, app, mod, act)
super().__init__(content)
@property
def application(self) -> str:
return self.get_str(key='app', default='')
@property
def module(self) -> str:
return self.get_str(key='mod', default='')
@property
def action(self) -> str:
return self.get_str(key='act', default='')
extends ID Address
Copyright © 2018 Albert Moky