Unity创建简单的Http服务器/客户端测试

服务器部分:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using UnityEngine;

/// <summary>
/// 服务器部分
/// </summary>
public class Sever_Yang : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        IniHttpServer();
    }

    // Update is called once per frame
    void Update()
    {
        
    }


    MyHttpServer HttpServer;
    public void IniHttpServer()
    {
        HttpServer = new MyHttpServer(new string[]
        {
               "http://127.0.0.1:8080/"
        });
        //绑定映射,处理函数
        //当传入URL为"http://127.0.0.1:8080/PostAGVC_Data/"时将调用PostAGVC_Data函数接收和解析
         HttpServer.AddRoute("/PostData_Login/", PostData_Login);
         //当传入URL为"http://127.0.0.1:8080/PostAGV_Data/"时将调用PostAGV_Data函数接收和解析
         HttpServer.AddRoute("/PostAGV_Data/", PostAGV_Data);
         HttpServer.Start();
    }


    public async Task<string> PostData_Login(HttpListenerContext context)
    {
        string httpMethod = context.Request.HttpMethod;
        string responseString = "";
        // 处理 POST 请求
        if (context.Request.HasEntityBody)
        {
            // 从请求主体中获取数据
            using (System.IO.Stream body = context.Request.InputStream)
            {
                using (System.IO.StreamReader reader = new System.IO.StreamReader(body, context.Request.ContentEncoding))
                {
                    string postData = reader.ReadToEnd(); // 读取 POST 数据
                                                          //处理数据
                    Debug.LogError(postData);                                    //。。。。。。。。。。。。
                                                          //。。。。。。。。。。。。
                                                          //返回字符串
                    responseString = "OK";
                }
            }
        }
        return responseString;
    }

    //与PostAGVC_Data内部类似,处理数据的代码不一样
    public async Task<string> PostAGV_Data(HttpListenerContext context)
    {
        //省略
        Console.WriteLine(111);
        return null;

    }
}


class MyHttpServer
{
    private readonly string mUrl; // 服务器监听的URL
    private readonly HttpListener mListener; // HttpListener实例
    private readonly Dictionary<string, Func<HttpListenerContext, Task<string>>> mRoutes; // 路由映射

    // 构造函数,接收服务器监听地址和端口的数组
    public MyHttpServer(string[] prefixes)
    {
        if (!HttpListener.IsSupported)
        {
            throw new NotSupportedException("HttpListener is not supported on this platform.");
        }

        mListener = new HttpListener(); // 初始化HttpListener实例
        mRoutes = new Dictionary<string, Func<HttpListenerContext, Task<string>>>(); // 初始化路由映射字典

        // 为服务器添加监听地址和端口
        foreach (string prefix in prefixes)
        {
            mListener.Prefixes.Add(prefix);
        }

        mUrl = prefixes[0]; // 记录第一个监听地址
    }

    public bool IsOpen { get { return mListener.IsListening; } }

    // 启动服务器
    public void Start()
    {
        mListener.Start();
        Console.WriteLine($"Server started and listening on {mUrl}");
        mListener.BeginGetContext(ProcessRequestCallback, mListener); // 处理客户端请求
    }

    // 停止服务器
    public void Stop()
    {
        mListener.Stop();
        mListener.Close();
        Console.WriteLine("Server stopped.");
    }

    // 添加路由和处理程序的映射关系
    public void AddRoute(string route, Func<HttpListenerContext, Task<string>> handler)
    {
        mRoutes.Add(route, handler);
    }

    // 处理客户端请求的回调函数
    private async void ProcessRequestCallback(IAsyncResult result)
    {
        HttpListener listener = (HttpListener)result.AsyncState;

        // 开始下一个请求的监听
        listener.BeginGetContext(ProcessRequestCallback, listener);

        try
        {
            // 获取传入的请求
            HttpListenerContext context = listener.EndGetContext(result);

            // 获取请求方法和URL路径
            string httpMethod = context.Request.HttpMethod;
            string responseString = "No Data!"; // 默认响应字符串
            string url = context.Request.Url.AbsolutePath;
            Func<HttpListenerContext, Task<string>> handler;

            // 如果请求路径存在于路由映射中,执行相应的处理程序
            if (mRoutes.TryGetValue(url, out handler))
            {
                responseString = await handler(context); // 获取处理程序返回的响应数据

                // 将响应数据编码成字节数组
                byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);

                // 设置响应的内容长度和状态码
                context.Response.ContentLength64 = buffer.Length;
                context.Response.StatusCode = (int)HttpStatusCode.OK;

                // 将响应写入输出流并关闭输出流
                context.Response.OutputStream.Write(buffer, 0, buffer.Length);
                context.Response.OutputStream.Close();
            }
            else
            {
                // 如果请求路径不存在于路由映射中,返回404 Not Found
                context.Response.StatusCode = (int)HttpStatusCode.NotFound;
                context.Response.Close();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error processing request: {ex.Message}");
        }
    }
}


客户端部分:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using UnityEngine;

/// <summary>
/// 客户端部分
/// </summary>
public class MyHttpClient : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        IniHttpClient();
    }
    HttpClient_DP HttpClient;
    public void IniHttpClient()
    {
        if (HttpClient == null)
        {
            HttpClient = new HttpClient_DP();
            HttpClient.TimeOut = TimeSpan.FromSeconds(10);
        }
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.A))
        {
            Debug.LogError("发送报文");
            //Debug.LogError(HttpClient.Post("http://192.168.9.12:8080/PostData_Login/", "发送报文格式"));
            SenMessage("PostData_Login","报文格式");
        }
    }

    public async void SenMessage(string _post, string _str)
    {
        string _pp = await HttpClient.Post(_post, _str,DisposeData);
    }

    //数据处理
    public void DisposeData(string _post, string _str)
    {
        Debug.LogError("接收端口" + _post + "  \n报文json:" + _str);
    
    }


}


public class HttpClient_DP
{
    private readonly HttpClient _client; // HttpClient 实例

    // 构造函数,初始化 HttpClient 实例
    public HttpClient_DP()
    {
        _client = new HttpClient();
    }

    // 设置超时时间
    public TimeSpan TimeOut { set { _client.Timeout = value; } }

    // 发送 GET 请求并返回响应内容
    public async Task<string> Get(string url)
    {
        HttpResponseMessage response = await _client.GetAsync(url); // 发送 GET 请求

        if (response.IsSuccessStatusCode)
        {
            string content = await response.Content.ReadAsStringAsync(); // 读取响应内容
            return content;
        }
        else
        {
            return $"Error: {response.StatusCode}"; // 返回错误信息
        }
    }

    // 发送 POST 请求并返回响应内容
    public async Task<string> Post(string _post, string data,Action<string,string> _ac)
    {
        var url = GetUrl(_post);
        HttpContent content = new StringContent(data); // 创建包含请求数据的 HttpContent 实例
        Debug.LogError(111);
        HttpResponseMessage response = await _client.PostAsync(url, content); // 发送 POST 请求

        Debug.Log(response.IsSuccessStatusCode);
        if (response.IsSuccessStatusCode)
        {
            string responseData = await response.Content.ReadAsStringAsync(); // 读取响应内容
            Debug.LogError(responseData);
            _ac?.Invoke(_post, responseData);
            return responseData;
        }
        else
        {
            return $"Error: {response.StatusCode}"; // 返回错误信息
        }
    }

    public string GetUrl(string _post)
    {
        return "http://127.0.0.1:8080/" + _post + "/";
    }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值