示例#1
0
 def run(self):
     # f**k
     loop = asyncio.new_event_loop()
     asyncio.set_event_loop(loop)
     loop = get_event_loop()
     loop.run_until_complete(self.asnyc_run())
     log('thread end')
示例#2
0
 def save_to_cache(self):
     user_key = 'user.' + str(self.user_id)
     user_cache = cache.get(user_key)
     user_cache['player_state'] = self.state
     log(self.name + 'saved to cache, state = ' + str(self.state))
     user_cache['room_id'] = self.room_id
     if 'channel_name' in user_cache:
         del user_cache['channel_name']
     cache.set(user_key, user_cache, timeout=USER_TTL)
示例#3
0
 def load_from_cache(self):
     user_key = 'user.' + str(self.user_id)
     user_cache = cache.get(user_key)
     user_cache['channel_name'] = self.channel_name
     cache.set(user_key, user_cache, timeout=USER_TTL)
     self.name = user_cache.get('name')
     self.state = user_cache.get('player_state', PlayerState.Out)
     self.room_id = user_cache.get('room_id')
     log(self.name + 'loaded from cache, state = ' + str(self.state))
示例#4
0
 async def asnyc_run(self):
     self.layer = channels.layers.get_channel_layer()
     log('Room', self.id, 'created')
     # clean old messages until get a 'hello'
     while True:
         msg = await self.layer.receive('room.' + self.id)
         if msg['type'] == 'hello':
             break
     while True:
         self.killer = Timer(ROOM_TTL, self.kill)
         self.killer.start()
         msg = await self.layer.receive('room.' + self.id)
         self.killer.cancel()
         if await self.process_msg(msg):
             break
     log('Room', self.id, 'disbanded')
示例#5
0
 def enter_room(self, room_id):
     room_key = 'room.' + room_id
     self.state = PlayerState.Waiting
     # 先收听频道,以获得频道解散消息
     log(self.name, 'add group:', room_key)
     async_to_sync(self.channel_layer.group_add)(room_key,
                                                 self.channel_name)
     self.room_id = room_id
     if not cache.get(room_key):
         self.leave_room()
         # 房间不存在或已经解散
         raise GameException('room not exist')
     self.send_msg_to_room({
         'type': 'enter',
         'name': self.name,
         'channel': self.channel_name,
     })
示例#6
0
 def receive_json(self, context):
     if len(context) == 0:
         self.send_json({})
         return
     try:
         log('recieve json from', self.name, ':')
         log(context)
         msg = context['msg']
         if msg in GameConsumer.msg_listener:
             GameConsumer.msg_listener[msg](self, context)
         else:
             self.send_error('type error: ' + msg)
     except KeyError as e:
         self.send_error('key error: ' + e.args[0])
     except GameException as e:
         self.send_error(str(e))
     except Exception:
         self.send_error('unkown server error')
         traceback.log_exc()
示例#7
0
 async def process_msg(self, msg):
     log('Room', self.id, 'get message:')
     log(msg)
     try:
         return await getattr(self, 'on_' + msg['type'],
                              self.on_error_msg)(msg)
     except GameException as e:
         player = self.find_player_by_id(msg['id'])
         if player and player.channel_name:
             channel_name = player.channel_name
         elif 'channel' in msg:
             channel_name = msg['channel']
         else:
             raise GameException(
                 'got error message from people not in the room, error =' +
                 e.msg)
         await self.post_msg_to(channel_name, {
             'msg': 'error',
             'error': str(e),
         })
示例#8
0
 def connect(self):
     session = self.scope['session']
     user_id = get_online_user_id(session)
     if user_id:
         self.accept()
         self.user_id = user_id
         self.load_from_cache()
         log('connect: user', self.name)
         self.send_json({
             'msg': 'connect',
             'id': self.user_id,
         })
         # 尝试连接房间(房间将下线同id的连接)
         if self.state != PlayerState.Out:
             log('try reconnect to room')
             self.try_reconnect_to_room()
     else:
         self.user_id = None
         self.accept()
         self.close(code=4233)
示例#9
0
 async def on_reconnect(self, msg):
     uid = msg['id']
     channel_name = msg['channel']
     log('on reconnect, uid =', uid, 'channel =', channel_name)
     player = self.find_player_by_id(uid)
     if player == None:
         log('player == None')
         raise GameException('not in room')
     else:
         if player.channel_name:
             await self.post_msg_to(player.channel_name, {
                 'msg': 'downlined',
             })
         player.channel_name = channel_name
         await self.post_msg({
             'msg': 'reconnect',
             'id': uid,
             'state': player.state.value,
             'room_type': self.type,
         })
         await self.post_msg_to(player.channel_name,
                                self.get_situation_msg(player))
示例#10
0
 def room_msg(self, event):
     log(self.name, 'get msg from room:')
     log(event)
     if event['msg'] == 'error' and event['error'] == 'not in room':
         self.leave_room()
         return
     # 设置状态改变
     if 'id' in event and event['id'] == self.user_id:
         state = {
             'enter': PlayerState.UnReady,
             'watch': PlayerState.Watching,
             'finish': PlayerState.Finished,
         }.get(event['msg'], None)
         if state == None and event['msg'] == 'reconnect':
             state = PlayerState(event.get('state'))
         if event['msg'] == 'change_state':
             state = PlayerState(event['state'])
         if state != None:
             self.state = state
             log('set state', state)
     if event['msg'] == 'start':
         self.state = PlayerState.Playing
     # 被下线
     if event['msg'] == 'downlined':
         self.close(code=4111)
         return
     # 如果房间解散,被禁止加入房间或者主动离场,则离开
     if event['msg'] == 'disband' \
         or (event['msg'] == 'leave' and event['id'] == self.user_id) \
         or (self.state == PlayerState.Waiting and event['msg'] == 'error'):
         self.leave_room()
     elif self.state == PlayerState.Waiting:
         # 尚未进入房间,其他消息与你无关
         return
     # 向客户端发送消息
     context = event.copy()
     context.pop('type')  # 这是Room与Customer传递消息用的,与客户端无关
     self.send_json(context)
示例#11
0
 async def on_error_msg(self, msg):
     log('Room', self.id, 'error message:', msg)
     raise GameException('unknown backend message type: ' +
                         str(msg['type']))
示例#12
0
 async def post_msg_to(self, channel_name, context):
     context['type'] = 'room.msg'
     log('Room', self.id, 'post message to channel', channel_name, ':')
     log(context)
     await self.layer.send(channel_name, context)
示例#13
0
 async def post_msg(self, context):
     context['type'] = 'room.msg'
     log('Room', self.id, 'post message:')
     log(context)
     await self.layer.group_send('room.' + self.id, context)
示例#14
0
 def send_error(self, msg):
     log('send error to', self.name, ':', msg)
     self.send_json({'msg': 'error', 'error': msg})