使用套接字时Unity延迟发送当前值
Unity delay in sending the current value when using sockets
Visual Studio中的client.cs。
private void SendToServer(string HeartRate)
{
SetHRTest(HeartRate);
try
{
s = client.GetStream();
StreamReader sr = new StreamReader(s);
StreamWriter sw = new StreamWriter(s);
sw.AutoFlush = true;
sw.WriteLine(HeartRate);
}
finally
{
if(Environment.HasShutdownStarted)
{
s.Close();
client.Close();
}
}
}
Unity中的server.cs
using UnityEngine;
using System.Collections;
using System.Net.Sockets;
using System.IO;
using System.Net;
using System.Threading;
public class Server {
public static TcpListener listener;
public static Socket soc;
public static NetworkStream s;
static public string CurrentHeartRate = "";
// Use this for initialization
public void StartService () {
listener = new TcpListener (15579);
listener.Start ();
for(int i = 0;i < 1;i++){
Thread t = new Thread(new ThreadStart(Service));
t.Start();
Debug.Log("3");
}
}
void Service () {
while (true)
{
soc = listener.AcceptSocket ();
s = new NetworkStream (soc);
StreamReader sr = new StreamReader (s);
StreamWriter sw = new StreamWriter (s);
sw.AutoFlush = true;
while(true)
{
string heartrate = sr.ReadLine ();
if(heartrate != null)
{
CurrentHeartRate = heartrate;
Debug.Log(heartrate);
}
else if (heartrate == null)
{
break;
}
}
s.Close();
}
}
void OnApplicationQuit()
{
Debug.Log ("END");
listener.Stop ();
s.Close();
soc.Close();
}
}
更新 3: 好的,我已经更新了两个脚本。服务器和客户端连接完全没有问题。当我检查服务器中的读数时,我能够看到更新的值。我现在唯一的问题是,延迟。每次改变心率值时都会启动客户端方法。当我将值设置为标签时,它会向我显示近乎实时的变化。但在服务器端,该值需要 6 秒才能赶上新值(此时已经发送了另一个新值)。希望有人能说清楚原因。
更新 4:没关系!我解决了这个问题。这是由于每次方法 运行 时都会初始化 TcpClient。这造成了延迟。我将其移至 Forms_Load 并注释掉了 s.Close() 和 client.Close()。延迟变得更少,接近一秒钟,这对我来说很好。不过现在,我只需要找出何时以及如何关闭流和 TcpClient。我正在尝试 Environment.HasShutdownStarted 检查应用程序何时关闭以关闭客户端和流,但它不起作用。
更新 5: 好的,使用 https://msdn.microsoft.com/en-us/library/system.windows.forms.application.applicationexit(v=vs.110).aspx 修复了最后一个问题!全部完成!
我认为这是因为您将所有服务器内容都放在了更新中。这意味着它会在每一帧被调用。这是很多。
您可能应该将所有这些放在一个单独的方法中,然后从客户端调用它。
您在每一帧开始和关闭流。
将 s、sr 和 sw 初始化移动到 Start 方法并使用 OnApplicationQuit 关闭。
void OnApplicationQuit()
{
s.Close();
soc.Close();
}
这样做 Unity 仍然会挂起 因为 ReadLine 不是异步的并且会锁定执行直到您的套接字接收到数据。
我能想到的前两种解决方法是:
- 使用线程
- 使用异步回调(我在 Unity 3D 中的 UDP 服务器中这样做)。看到这个问题:What is AsyncCallback?
Visual Studio中的client.cs。
private void SendToServer(string HeartRate)
{
SetHRTest(HeartRate);
try
{
s = client.GetStream();
StreamReader sr = new StreamReader(s);
StreamWriter sw = new StreamWriter(s);
sw.AutoFlush = true;
sw.WriteLine(HeartRate);
}
finally
{
if(Environment.HasShutdownStarted)
{
s.Close();
client.Close();
}
}
}
Unity中的server.cs
using UnityEngine;
using System.Collections;
using System.Net.Sockets;
using System.IO;
using System.Net;
using System.Threading;
public class Server {
public static TcpListener listener;
public static Socket soc;
public static NetworkStream s;
static public string CurrentHeartRate = "";
// Use this for initialization
public void StartService () {
listener = new TcpListener (15579);
listener.Start ();
for(int i = 0;i < 1;i++){
Thread t = new Thread(new ThreadStart(Service));
t.Start();
Debug.Log("3");
}
}
void Service () {
while (true)
{
soc = listener.AcceptSocket ();
s = new NetworkStream (soc);
StreamReader sr = new StreamReader (s);
StreamWriter sw = new StreamWriter (s);
sw.AutoFlush = true;
while(true)
{
string heartrate = sr.ReadLine ();
if(heartrate != null)
{
CurrentHeartRate = heartrate;
Debug.Log(heartrate);
}
else if (heartrate == null)
{
break;
}
}
s.Close();
}
}
void OnApplicationQuit()
{
Debug.Log ("END");
listener.Stop ();
s.Close();
soc.Close();
}
}
更新 3: 好的,我已经更新了两个脚本。服务器和客户端连接完全没有问题。当我检查服务器中的读数时,我能够看到更新的值。我现在唯一的问题是,延迟。每次改变心率值时都会启动客户端方法。当我将值设置为标签时,它会向我显示近乎实时的变化。但在服务器端,该值需要 6 秒才能赶上新值(此时已经发送了另一个新值)。希望有人能说清楚原因。
更新 4:没关系!我解决了这个问题。这是由于每次方法 运行 时都会初始化 TcpClient。这造成了延迟。我将其移至 Forms_Load 并注释掉了 s.Close() 和 client.Close()。延迟变得更少,接近一秒钟,这对我来说很好。不过现在,我只需要找出何时以及如何关闭流和 TcpClient。我正在尝试 Environment.HasShutdownStarted 检查应用程序何时关闭以关闭客户端和流,但它不起作用。
更新 5: 好的,使用 https://msdn.microsoft.com/en-us/library/system.windows.forms.application.applicationexit(v=vs.110).aspx 修复了最后一个问题!全部完成!
我认为这是因为您将所有服务器内容都放在了更新中。这意味着它会在每一帧被调用。这是很多。
您可能应该将所有这些放在一个单独的方法中,然后从客户端调用它。
您在每一帧开始和关闭流。 将 s、sr 和 sw 初始化移动到 Start 方法并使用 OnApplicationQuit 关闭。
void OnApplicationQuit()
{
s.Close();
soc.Close();
}
这样做 Unity 仍然会挂起 因为 ReadLine 不是异步的并且会锁定执行直到您的套接字接收到数据。
我能想到的前两种解决方法是:
- 使用线程
- 使用异步回调(我在 Unity 3D 中的 UDP 服务器中这样做)。看到这个问题:What is AsyncCallback?