一个简单的C#HTTP服务器(含Unity通信调用)

为什么会有这个需求呢,是这样的,我们希望在手机端能够实时的把日志汇报到一个测试用的服务器上。因为本人是客户端,而且也不想占用服务器资源。因此就想自己尝试一下能不能直接用C#实现一个简单的http服务器,搜了一些资料后发现。一种是用Socket实现,一种是用HttpListener实现。Socket的实现不够直观明朗,但是更灵活。因为我的需求就是期望客户端那用简单的http请求就可以把游戏内日志汇报上来,因此简单易用是第一需求。

原作者找不到了,这是我找到的那个参考

https://www.h3399.cn/201709/136120.html

在他的基础上,我经过修改测试,整理了一个可用的代码如下:

我是VS2019的一个WinForm工程

    class SimpleHttpServer
    {
        private HttpListener _listener;
        public SendOrPostCallback Handler = null;
        public SynchronizationContext UiContext = null;

        private void RequestHandler(IAsyncResult result)
        {
            try
            {
                HttpListenerContext context = _listener.EndGetContext(result);
                byte[] buffer = new byte[8096];
                using (Stream stream = context.Request.InputStream)
                {
                    int count = 0;
                    while ((count = stream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        UiContext.Send(Handler, Encoding.UTF8.GetString(buffer, 0, count));
                    }
                }
                StreamWriter sw = new StreamWriter(context.Response.OutputStream, Encoding.UTF8);
                context.Response.ContentType = "text/html";
                context.Response.ContentEncoding = Encoding.UTF8;
                context.Response.Close();
            }
            catch (Exception e)
            {
                //
            }
            finally
            {
                if (_listener.IsListening)
                {
                    _listener.BeginGetContext(RequestHandler, new object());
                }
            }
        }

        public void Start()
        {
            _listener = new HttpListener();
            _listener.Prefixes.Add("http://+:10086/");
            _listener.Start();
            _listener.BeginGetContext(RequestHandler, new object());
        }

        public void Close()
        {
            _listener.Stop();
            _listener.Abort();
        }
    }

请注意,这里我什么也没有返回,因为我需要的就是仅接受到消息就OK

启用的时候,在界面初始化的时候,调用Start()方法即可,然后测试可以在浏览器上输入局域网的IP地址测试

例如http://192.168.xx.xx:10086

这里10086也是自己随便定义的一个端口,如果显示一个空白的页面,证明消息就收到了。

try内是服务器收到请求的处理,因为我是用Winform做的,涉及到一个UI线程同步问题,因此用了SynchronizationContext 来处理。实际上可以根据自己的需求去处理这个string字段

在Unity里,可以用UnityWebRequest来简单模拟,这样调用

using (UnityWebRequest unityWebRequest = new UnityWebRequest(_uri, UnityWebRequest.kHttpVerbPOST))
{
    unityWebRequest.uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(log))
    {
        contentType = "application/x-www-form-urlencoded"
    };

    unityWebRequest.timeout = 3;
    unityWebRequest.useHttpContinue = false;
    yield return unityWebRequest.SendWebRequest();
}

log就是我们要发送的日志内容本身。

需要注意的一点是,运行服务器的主机一定要关掉防火墙,或者加入白名单,不然会有可能造成别的机器无法访问的问题。另外我只测试了内网。外网的情况下,可能需要IP映射

附:

在安卓上测试也是OK的,还没在Ios上测试,后续测试过了也补充进来

另外,unity可以通过

Application.logMessageReceivedThreaded += OnLogHandle

方法来监听所有日志,在应用里,只需要添加自己处理日志的方法即可。为了不阻塞游戏,请做个缓存队列~不然经常卡死unity。试想,如果你在错误日志处理里也出错,这个错误又会触发错误日志处理,就直接死循环了。反正要注意下这个问题

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是用TCP协议通信Unity客户端代码示例,用于接收服务器数据: ``` using UnityEngine; using System.Net.Sockets; using System; public class TCPClient : MonoBehaviour { private TcpClient client; private NetworkStream stream; private byte[] receiveBuffer = new byte[1024]; public void ConnectToServer(string serverIP, int serverPort) { try { client = new TcpClient(serverIP, serverPort); stream = client.GetStream(); Debug.Log("Connected to server."); // Send any initial messages to server here if needed // ... // Start listening for server messages BeginReceive(); } catch (Exception e) { Debug.LogError("Failed to connect to server: " + e.Message); } } private void BeginReceive() { stream.BeginRead(receiveBuffer, 0, receiveBuffer.Length, OnReceive, null); } private void OnReceive(IAsyncResult ar) { int bytesRead = stream.EndRead(ar); if (bytesRead > 0) { string message = System.Text.Encoding.ASCII.GetString(receiveBuffer, 0, bytesRead); Debug.Log("Received message from server: " + message); // Process the received message here as needed // ... // Start listening for more server messages BeginReceive(); } else { Debug.LogError("Connection to server closed."); // Handle disconnection from server here if needed // ... } } public void SendMessageToServer(string message) { if (client == null || !client.Connected) { Debug.LogError("Not connected to server."); return; } try { byte[] messageBytes = System.Text.Encoding.ASCII.GetBytes(message); stream.Write(messageBytes, 0, messageBytes.Length); Debug.Log("Sent message to server: " + message); } catch (Exception e) { Debug.LogError("Failed to send message to server: " + e.Message); } } private void OnDestroy() { if (client != null) { client.Close(); client = null; } } } ``` 使用方法: 1. 在Unity中创建一个空对象并将此脚本组件添加到它上面。 2. 在需要连接到服务器的地方调用`ConnectToServer()`方法,传入服务器IP和端口号。 3. 在需要向服务器发送消息的地方调用`SendMessageToServer()`方法,传入要发送的消息。 4. 当从服务器接收到消息时,将调用`OnReceive()`方法并处理接收到的消息。 5. 当与服务器的连接断开时,将调用`OnDestroy()`方法并清理资源。 请注意,此代码示例仅演示了基本的TCP连接和数据传输,不包括错误处理和其他高级功能,例如安全性和可靠性。在实际使用中,您需要进行适当的错误处理和添加所需的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值