using System.Collections; using System.Collections.Generic; using UnityEngine; using WebSocketSharp.Server; using System; using System.Net; using System.Text; using Newtonsoft.Json.Linq; using Newtonsoft.Json; public class MyServer : MonoBehaviour { public static MyServer instance; public static string version = "1.0"; WebSocketServer wss; HttpListener httpobj; [HideInInspector] public Queue reciveData = new Queue(); Action handleFun_szr = null; Action handleFun_jqr = null; Action handleFun_wrj = null; Action handleFun_other = null; [HideInInspector] public ServerHandler handler = null; public Queue console_log_message = new Queue(); public Queue console_warning_message = new Queue(); public Queue console_error_message = new Queue(); private void Awake() { instance = this; } private void Start() { StartWebsocketServer(10088); //StartWebsocketServer(6001); //StartHttpServer(10089); } private void OnDestroy() { StopWebsocketServer(); } private void Update() { if (reciveData.Count > 0) { int count = reciveData.Count; for (int i = 0; i < count; i++) { if (reciveData.TryDequeue(out JObject result)) { if (result["type"].ToString() == "szr") { if (handleFun_szr != null) handleFun_szr(result); } else if (result["type"].ToString() == "jqr") { if (handleFun_jqr != null) handleFun_jqr(result); } else if (result["type"].ToString() == "wrj") { if (handleFun_wrj != null) handleFun_wrj(result); } else { if (handleFun_other != null) handleFun_other(result); } } } } if (console_log_message.Count > 0) { Console(console_log_message.Dequeue()); } if (console_warning_message.Count > 0) { Console(console_log_message.Dequeue(), "warning"); } if (console_error_message.Count > 0) { Console(console_log_message.Dequeue(), "error"); } } void StartA() { Debug.Log("调用成功"); //handleFun_szr } void Console(string _message, string _type = "log") { if (ConsolePanel.Instance != null) ConsolePanel.ConsoleOutput(_message, _type);//输出连接状态 } /// /// 启动消息监听 /// /// private void StartWebsocketServer(int port) { try { string text = "ws://0.0.0.0:" + port; //string text = "ws://172.16.1.17:10088"; wss = new WebSocketServer(text); wss.AddWebSocketService("/cxx"); wss.KeepClean = false; wss.Start(); Debug.Log("开始监听,端口:" + port); } catch (Exception ex) { Debug.LogError(ex.Message); } } /// /// 关闭消息监听 /// private void StopWebsocketServer() { if (wss != null) { wss.RemoveWebSocketService("/cxx"); wss.Stop(); wss = null; Debug.Log("关闭监听"); } } /* #region http private void StartHttpServer(int port) { httpobj = new HttpListener(); //定义url及端口号,通常设置为配置文件 httpobj.Prefixes.Add("http://127.0.0.1:" + port + "/cxx/"); //启动监听器 httpobj.Start(); //异步监听客户端请求,当客户端的网络请求到来时会自动执行Result委托 //该委托没有返回值,有一个IAsyncResult接口的参数,可通过该参数获取context对象 httpobj.BeginGetContext(Result, null); Debug.Log("httpserver 初始化完成"); } private void StopHttpServer() { } */ private void Result(IAsyncResult ar) { //当接收到请求后程序流会走到这里 //继续异步监听 httpobj.BeginGetContext(Result, null); var guid = Guid.NewGuid().ToString(); Debug.Log($"接到新的请求:{guid},时间:{DateTime.Now.ToString()}"); //获得context对象 var context = httpobj.EndGetContext(ar); var request = context.Request; var response = context.Response; ////如果是js的ajax请求,还可以设置跨域的ip地址与参数 //context.Response.AppendHeader("Access-Control-Allow-Origin", "*");//后台跨域请求,通常设置为配置文件 //context.Response.AppendHeader("Access-Control-Allow-Headers", "ID,PW");//后台跨域参数设置,通常设置为配置文件 //context.Response.AppendHeader("Access-Control-Allow-Method", "post");//后台跨域请求设置,通常设置为配置文件 context.Response.ContentType = "text/plain;charset=UTF-8";//告诉客户端返回的ContentType类型为纯文本格式,编码为UTF-8 context.Response.AddHeader("Content-type", "text/plain");//添加响应头信息 context.Response.ContentEncoding = Encoding.UTF8; string returnObj = null;//定义返回客户端的信息 if (request.HttpMethod == "POST" && request.InputStream != null) { //处理客户端发送的请求并返回处理信息 returnObj = HandleRequest(request, response); } else { returnObj = $"不是post请求或者传过来的数据为空"; } var returnByteArr = Encoding.UTF8.GetBytes(returnObj);//设置客户端返回信息的编码 try { using (var stream = response.OutputStream) { //把处理信息返回到客户端 stream.Write(returnByteArr, 0, returnByteArr.Length); } } catch (Exception ex) { Debug.LogError($"网络蹦了:{ex.ToString()}"); } Debug.Log($"请求处理完成:{guid},时间:{DateTime.Now.ToString()}\r\n"); } private string HandleRequest(HttpListenerRequest request, HttpListenerResponse response) { string data = null; try { var byteList = new List(); var byteArr = new byte[2048]; int readLen = 0; int len = 0; //接收客户端传过来的数据并转成字符串类型 do { readLen = request.InputStream.Read(byteArr, 0, byteArr.Length); len += readLen; byteList.AddRange(byteArr); } while (readLen != 0); data = Encoding.UTF8.GetString(byteList.ToArray(), 0, len); //获取得到数据data可以进行其他操作 } catch (Exception ex) { response.StatusDescription = "404"; response.StatusCode = 404; Debug.LogError($"在接收数据时发生错误:{ex.ToString()}"); return $"在接收数据时发生错误:{ex.ToString()}";//把服务端错误信息直接返回可能会导致信息不安全,此处仅供参考 } response.StatusDescription = "200";//获取或设置返回给客户端的 HTTP 状态代码的文本说明。 response.StatusCode = 200;// 获取或设置返回给客户端的 HTTP 状态代码。 Debug.Log($"接收数据完成:{data.Trim()},时间:{DateTime.Now.ToString()}"); return $"接收数据完成"; } //#endregion /// /// 添加数字人消息处理方法 /// /// json,消息一定包含以下字段:int eventid(操作id),string commond 指令 public void SetHandler_szr(Action handlerFun) { handleFun_szr = handlerFun; } /// /// 添加机器人消息处理方法 /// /// json,消息一定包含以下字段:int eventid(操作id),string commond 指令 public void SetHandler_jqr(Action handlerFun) { handleFun_jqr = handlerFun; } /// /// 添加无人机消息处理方法 /// /// json,消息一定包含以下字段:int eventid(操作id),string commond 指令 public void SetHandler_wrj(Action handlerFun) { handleFun_wrj = handlerFun; } /// /// 添加其它类型消息处理方法 /// /// json,消息一定包含以下字段:int eventid(操作id),string commond 指令 public void SetHandler_other(Action handlerFun) { handleFun_other = handlerFun; } /// /// 发送消息, (完全版,可添加自定义字段) /// /// json格式,当回复消息时必须包含以下几个字段:int eventid(回复id),ResultState result(结果),string msg(失败字段) public void SendMsgToSDK(string msg) { if (handler != null) { handler.SendMsg(msg); } } /// /// 发送消息,(简易版,只包含基础字段) /// /// /// /// public void SendMsgToSDK(int event_id, ResultStatus result, string msg = null) { if (result != ResultStatus.SUCCESS && msg == null) { Debug.LogError("失败必须传原因"); } else { if (handler != null) { handler.SendMsg(JsonConvert.SerializeObject(new { event_id = event_id, result = result, msg = msg == null ? "" : msg })); } } } } /// /// 回复的级别 /// public enum ResultStatus { SUCCESS = 1, /// /// 此操作失败,本次仿真测试继续进行 /// FAILED_WARNING = 2, /// /// 此操作失败,本次仿真测试中断 /// FAILED_ERROR = 3 }