async public Task<JoinRoomResponse> JoinRoom(JoinRoomS2S request) { if (_roomMembers.Count >= MaxRoomSize) return new JoinRoomResponse { RetCode = JoinRoomRetCode.RoomIsFull }; else { if (_roomMembers.Any(x => x.UserName == request.UserName)) return new JoinRoomResponse { RetCode = JoinRoomRetCode.NameIsTaken }; try { var joinNotification = new RoomEvent { Text = "User joined", UserName = request.UserName }; _callbackChannel.OnRoomEvent(joinNotification); _roomMembers.Add(new RoomMember { UserName = request.UserName }); return new JoinRoomResponse { RetCode = JoinRoomRetCode.Ok }; } catch (Exception) { return new JoinRoomResponse() { RetCode = JoinRoomRetCode.Retry }; } } }
async public Task<JoinRoomResponse> Process(JoinRoomS2S request, IOperationContext context) { if (_roomMembers.Count >= MaxRoomSize) return new JoinRoomResponse { RetCode = JoinRoomRetCode.RoomIsFull }; else { if (_roomMembers.Any(x => x.UserName == request.UserName)) return new JoinRoomResponse { RetCode = JoinRoomRetCode.NameIsTaken }; _state = await _stateManager.GetOrAddAsync<IReliableDictionary<string, DateTime>>(ActorRef.Key.Id); try { var callbackChannel = await _node.ConnectToCallbackChannel(request.CallbackChannelRef); callbackChannel.DisconnectedEvent .Subscribe(_ => Fiber.Process(() => { _roomMembers.RemoveAll(x => x.UserName == request.UserName); var leaveNotification = new RoomEvent { Text = "User left", UserName = request.UserName }; foreach (var roomMember in _roomMembers) { roomMember.CallbackChannel.Send(leaveNotification); } if (_roomMembers.Count == 0) Dispose(); })); var joinNotification = new RoomEvent { Text = "User joined", UserName = request.UserName }; foreach (var roomMember in _roomMembers) { roomMember.CallbackChannel.Send(joinNotification); } _roomMembers.Add(new RoomMember { UserName = request.UserName, CallbackChannel = callbackChannel }); return new JoinRoomResponse { RetCode = JoinRoomRetCode.Ok }; } catch (Exception) { return new JoinRoomResponse() { RetCode = JoinRoomRetCode.Retry }; } } }
async Task<JoinRoomResponse> OnRoomJoin(JoinRoom msg, IOperationContext context) { var room = await _rooms.GetActor(new ActorKey(msg.RoomName)); var callbackRef = _callbacksNode.ExposeAsCallbackChannel(this); var joinRoomOnServer = new JoinRoomS2S() { CallbackChannelRef = callbackRef, RoomName = msg.RoomName, UserName = msg.UserName }; var reply = await room.SendAsync<JoinRoomResponse>(joinRoomOnServer, context); if (reply.RetCode == JoinRoomRetCode.Ok) { _room = room; _userName = msg.UserName; } return reply; }
async Task<JoinRoomResponse> OnRoomJoin(JoinRoom msg, IOperationContext context) { var room = ActorProxy.Create<ISFRoomActor>(new ActorId(msg.RoomName)); await room.SubscribeAsync(this); var joinRoomOnServer = new JoinRoomS2S() { RoomName = msg.RoomName, UserName = msg.UserName }; var reply = await room.JoinRoom(joinRoomOnServer); if (reply.RetCode == JoinRoomRetCode.Ok) { _room = room; _userName = msg.UserName; } return reply; }