OnMessage 中的 websocket-sharp 统一性问题
websocket-sharp unity problem in OnMessage
我正在制作游戏
在我的游戏大厅部分,使用网络套接字接收该房间的开场者列表
如果接收规范的时间间隔即使是2秒,工作也没有问题,但如果同时接收所有规范,MakeUILobby功能将无法使用!
public IEnumerator Start()
{
ws = new WebSocket("ws://localhost:8081");
ws.SetCookie();
ws.Connect();
WSConnectionStatus = true;
ws.OnMessage += (sender, e) =>
{
WSUserJoinedToRoom = JsonUtility.FromJson<WSUserJoinedToRoom>(e.Data);
print("Message Received from " + ((WebSocket)sender).Url + ", Data : " + e.Data);
_actions.Enqueue(() => MakeUILobby(WSUserJoinedToRoom.user_id, WSUserJoinedToRoom.user_name));
};
}
private void MakeUILobby(string user_id, string user_name)
{
print(user_name);
}
WebSocket 数据第 1 部分:
{"user_id": "3", "user_name": "Player-3"}
WebSocket 数据第 2 部分:
{"user_id": "1", "user_name": "Player-1"}
但是如果你看上图,MakeUILobby 函数被调用了两次,其中包含玩家的信息,如果它应该像下图那样!
您的问题是value capturing in lambda expressions。
字段 WSUserJoinedToRoom
的值在每次收到最后一个项目时都会更改,因此当主线程帧播放时,它将执行两个 lambda 操作,这两个操作都将访问相同的 WSUserJoinedToRoom
值。
所以在你的情况下
- 玩家 3 被接收并存储到
WSUserJoinedToRoom
并且您添加回调操作
- 玩家 1 被接收并存储到
WSUserJoinedToRoom
并且您添加回调操作
- 现在主线程执行更新并执行从 current
WSUserJoinedToRoom
(玩家1), 不是 回调 Enqueue
d! 时的回调
而是将两个字符串存储在局部变量之前:
ws.OnMessage += (sender, e) =>
{
WSUserJoinedToRoom = JsonUtility.FromJson<WSUserJoinedToRoom>(e.Data);
print("Message Received from " + ((WebSocket)sender).Url + ", Data : " + e.Data);
// HERE: Store new variables for the values
var userId = WSUserJoinedToRoom.user_id;
var userName = WSUserJoinedToRoom.user_name;
_actions.Enqueue(() => MakeUILobby(userId, userName));
};
或者根本不使用 WSUserJoinedToRoom
的字段,而是
ws.OnMessage += (sender, e) =>
{
// HERE: Simply make a new variable everytime
var WSUserJoinedToRoom = JsonUtility.FromJson<WSUserJoinedToRoom>(e.Data);
print("Message Received from " + ((WebSocket)sender).Url + ", Data : " + e.Data);
_actions.Enqueue(() => MakeUILobby(WSUserJoinedToRoom.user_id, WSUserJoinedToRoom.user_name));
};
我正在制作游戏 在我的游戏大厅部分,使用网络套接字接收该房间的开场者列表 如果接收规范的时间间隔即使是2秒,工作也没有问题,但如果同时接收所有规范,MakeUILobby功能将无法使用!
public IEnumerator Start()
{
ws = new WebSocket("ws://localhost:8081");
ws.SetCookie();
ws.Connect();
WSConnectionStatus = true;
ws.OnMessage += (sender, e) =>
{
WSUserJoinedToRoom = JsonUtility.FromJson<WSUserJoinedToRoom>(e.Data);
print("Message Received from " + ((WebSocket)sender).Url + ", Data : " + e.Data);
_actions.Enqueue(() => MakeUILobby(WSUserJoinedToRoom.user_id, WSUserJoinedToRoom.user_name));
};
}
private void MakeUILobby(string user_id, string user_name)
{
print(user_name);
}
WebSocket 数据第 1 部分:
{"user_id": "3", "user_name": "Player-3"}
WebSocket 数据第 2 部分:
{"user_id": "1", "user_name": "Player-1"}
但是如果你看上图,MakeUILobby 函数被调用了两次,其中包含玩家的信息,如果它应该像下图那样!
您的问题是value capturing in lambda expressions。
字段 WSUserJoinedToRoom
的值在每次收到最后一个项目时都会更改,因此当主线程帧播放时,它将执行两个 lambda 操作,这两个操作都将访问相同的 WSUserJoinedToRoom
值。
所以在你的情况下
- 玩家 3 被接收并存储到
WSUserJoinedToRoom
并且您添加回调操作 - 玩家 1 被接收并存储到
WSUserJoinedToRoom
并且您添加回调操作 - 现在主线程执行更新并执行从 current
WSUserJoinedToRoom
(玩家1), 不是 回调Enqueue
d! 时的回调
而是将两个字符串存储在局部变量之前:
ws.OnMessage += (sender, e) =>
{
WSUserJoinedToRoom = JsonUtility.FromJson<WSUserJoinedToRoom>(e.Data);
print("Message Received from " + ((WebSocket)sender).Url + ", Data : " + e.Data);
// HERE: Store new variables for the values
var userId = WSUserJoinedToRoom.user_id;
var userName = WSUserJoinedToRoom.user_name;
_actions.Enqueue(() => MakeUILobby(userId, userName));
};
或者根本不使用 WSUserJoinedToRoom
的字段,而是
ws.OnMessage += (sender, e) =>
{
// HERE: Simply make a new variable everytime
var WSUserJoinedToRoom = JsonUtility.FromJson<WSUserJoinedToRoom>(e.Data);
print("Message Received from " + ((WebSocket)sender).Url + ", Data : " + e.Data);
_actions.Enqueue(() => MakeUILobby(WSUserJoinedToRoom.user_id, WSUserJoinedToRoom.user_name));
};