我有一个Netty游戏服务器,它发送带有空分隔符的JSON消息.我有一个AS3客户端与该服务器正常通信,但我们的新Unity客户端无法正常通信,可能是由于消息发送的顺序.有时我在解析JSON字符串时会遇到异常,特别是对于长消息.我try 了不同的缓冲区大小,但没有任何变化.
try {
_tcpClient = new TcpClient();
await _tcpClient.ConnectAsync(_host, _port);
_isListening = true;
Debug.Log("Connected...");
UnityMainThreadDispatcher.Instance().Enqueue(DispatchConnected());
Byte[] bytes = new Byte[BufferSize];
StringBuilder partialMessage = new();
while (_isListening && !_stopRequested) {
if (_tcpClient != null && _tcpClient.Connected) {
using (NetworkStream stream = _tcpClient.GetStream()) {
if (stream.CanRead) {
try {
int bytesRead;
while ((bytesRead = stream.Read(bytes, 0, BufferSize)) > 0) {
string bufferMessage = Encoding.UTF8.GetString(bytes, 0, bytesRead);
// Append the buffer to the existing partial message
partialMessage.Append(bufferMessage);
// Check if the partial message contains the termination character
int terminateIndex;
while ((terminateIndex = partialMessage.ToString().IndexOf(TerminateCharacter)) != -1) {
string completeMessage = partialMessage.ToString(0, terminateIndex);
Debug.Log("R: " + completeMessage);
UnityMainThreadDispatcher.Instance().Enqueue(DispatchServerMessage(completeMessage, true)); // <-- This is where I convert to JSON
// Remove the processed portion from the partial message
partialMessage.Remove(0, terminateIndex + 1);
}
}
}
catch (IOException ioException) {
Debug.LogError($"IOException: {ioException.Message}");
}
catch (Exception exception) {
Debug.LogError(exception);
}
}
}
}
else {
Debug.Log("TCP Client is not connected!");
ClientDisconnected();
break; // Break out of the loop when the client is not connected
}
}
// Process any remaining partial message after the loop
if (partialMessage.Length > 0) {
UnityMainThreadDispatcher.Instance().Enqueue(DispatchServerMessage(partialMessage.ToString(), true));
partialMessage.Clear();
}
}
catch (SocketException socketException) {
if (socketException.ErrorCode == 10061) {
// Debug.LogError("Connection refused!!!");
UnityMainThreadDispatcher.Instance().Enqueue(DispatchConnectionRefused());
}
else {
UnityMainThreadDispatcher.Instance().Enqueue(DispatchConnectionInterrupted());
}
}
catch (IOException ioException) {
UnityMainThreadDispatcher.Instance().Enqueue(DispatchConnectionInterrupted());
// UnityMainThreadDispatcher.Instance().Enqueue(DispatchConnectionRefused());
}
finally
{
_stopRequested = true; // Ensure the thread stops even if an exception occurs
_tcpClient?.Close();
_clientReceiveThread = null;
}
当我查看错误时,我可以看到一些消息以一种无序的方式出现.例如,假设服务器发送三条带有空分隔符Hello\0Socket\0World
的消息,我的客户端收到Socket->;Hello->;World.
有没有更好的方法来处理JSON消息?这里可能出了什么问题?如果是服务器问题,AS3客户端也会出现错误.
下面是netty初始化器代码.
ChannelPipeline pipeline = socketChannel.pipeline();
pipeline.addLast("timeout", new IdleStateHandler(ServerSettings.MAX_IDLE_TIME_IN_SECONDS, 0, ServerSettings.MAX_IDLE_TIME_IN_SECONDS));
pipeline.addLast(new DelimiterBasedFrameDecoder(1024 * 1024, Delimiters.nulDelimiter()));
pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));// (2)
pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8)); // (1)
pipeline.addLast(new SimpleTCPHandler()); // (3)
谢谢