Benjamin

静以修身,俭以养德,非澹薄无以明志,非宁静无以致远。
随笔 - 262, 文章 - 0, 评论 - 196, 引用 - 0
数据加载中……

python在tornado下websocket客户端

from tornado import httpclient
from tornado import ioloop
from tornado import websocket
import uuid
import binascii
import struct
import weakref
DEFAULT_CONNECT_TIMEOUT = 60
DEFAULT_REQUEST_TIMEOUT = 60
def my_unpack(message1, length,ag_client):
    """解包"""
    message = message1[length:len(message1)]
    # 获取cmd
    cmd, = struct.unpack('!i', message[0:4])
    # 获取长度
    size, = struct.unpack('!i', message[4:8])
    if size!=len(message):
        print('接收字节长度=%d' % (len(message)))
        print('包头中包长度=%d' % size)
        print('cmd=====%d'%cmd)
    #包头中的长度比包长度大,丢弃,不完整包
    if size >len(message):
        print('坏包丢弃')
        return
    # 包内容
    string, = struct.unpack('!{0}s'.format(size - 4), message[4:size])
    from protocol.deserialize import ag_parse
    ag_parse(cmd, string, ag_client)
    length += size
    if len(message) > size:
        my_unpack(message1, length,ag_client)
class WebSocketClient(object):
    """Base for web socket clients.
    """
    def __init__(self, *, connect_timeout = DEFAULT_CONNECT_TIMEOUT,
                          request_timeout = DEFAULT_REQUEST_TIMEOUT,
                          name = login_name,
                          passwd = login_password,
                          player = None):
        self.connect_timeout = connect_timeout
        self.request_timeout = request_timeout
        #玩家登陆名
        self.player_name = name
        #玩家登陆passwd
        self.player_passwd = passwd
        #玩家数据
        if player:
            self.player = weakref.proxy(player)
        else:
            self.player = None
    def connect(self, url):
        """Connect to the server.
        :param str url: server URL.
        """
        request = httpclient.HTTPRequest(url=url,
                                         connect_timeout=self.connect_timeout,
                                         request_timeout=self.request_timeout)
        ws_conn = websocket.WebSocketClientConnection(request,ioloop.IOLoop.current())
        ws_conn.connect_future.add_done_callback(self._connect_callback)
        ws_conn.on_message=self._on_message
        ws_conn.on_connection_close=self._on_connection_close
    def send(self, data):
        """Send message to the server
        :param str data: message.
        """
        if not self._ws_connection:
            raise RuntimeError('Web socket connection is closed.')
        self._ws_connection.write_message(data,True)
    def close(self):
        """Close connection.
        """
        if not self._ws_connection:
            raise RuntimeError('Web socket connection is already closed.')
        self._ws_connection.close()
    def _connect_callback(self, future):
        if future.exception() is None:
            self._ws_connection = future.result()
            self._on_connection_success()
        else:
            self._on_connection_error(future.exception())
    def _on_message(self, msg):
        """This is called when new message is available from the server.
        :param str msg: server message.
        """
        pass
    def _on_connection_success(self):
        """This is called on successful connection ot the server.
        """
        pass
    def _on_connection_close(self):
        """This is called when server closed the connection.
        """
        pass
    def _on_connection_error(self, exception):
        """This is called in case if connection to the server could
        not established.
        """
        pass
    def bind(self,player):
        pass
class AppWebSocketClient(WebSocketClient):
    def _on_message(self, msg):
        my_unpack(msg, 0, self)
    def _on_connection_success(self):
        print('Connected!')
        self.bind(self.player)
        def intToBytes(value, length):
            resu = []
            for i in range(0, length):
                resu.append(value >> (i * 8) & 0xff)
            resu.reverse()
            return resu
        login_pack = packet_pb2.PK_CLIENT_LOGIN()
        #用户名
         login_pack.loginname = self.player_name
     
        #密码
        curr_password = self.player_passwd
        login_pack.devicetype = 1
        result = []
        temp = b''
        for i in range(0, len(curr_password), 2):
            result.append(binascii.unhexlify(curr_password[i:i + 2]))
            temp += (binascii.unhexlify(curr_password[i:i + 2]))
        login_pack.token = temp
        # 序列化
        serializeToString = login_pack.SerializeToString()
        print(serializeToString, type(serializeToString))
        args = (704, len(serializeToString), 0, 1, 1, serializeToString)
        fmt = ">iiihh{0}s".format(len(serializeToString))
        data = struct.pack(fmt, *args)
        self.send(data)
    def _on_connection_close(self):
        print('Connection closed!')
        self._ws_connection.tcp_client.close()
        print('关闭socket,重新连接')
        # self.connect(ag_url)
    def _on_connection_error(self, exception):
        print('Connection error: %s', exception)
    def bind(self,player):
        """绑定ag的wss连接"""
        if player:
            if player.ag_wss:
                player.ag_wss.close()
            self.player.ag_wss = self
            print('!!!!!!绑定到ag完成!!!!!!')
def player_client(name,passwd,table_id,player):
    """玩家登陆创建客户端"""
    if name:
        if passwd:
            if table_id > 0xFFFE:
                if player:
                    client = AppWebSocketClient(connect_timeout=DEFAULT_CONNECT_TIMEOUT,
                                                request_timeout=DEFAULT_REQUEST_TIMEOUT,
                                                name=name,
                                                passwd=passwd,
                                                player= player)
                    client.connect(ag_url)

posted on 2020-01-03 19:41 Benjamin 阅读(38) 评论(0)  编辑 收藏 引用 所属分类: python


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理