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 };
}
}
}