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)