ict.shenzhi/Assets/Scripts/cxx/MyServer.cs

340 lines
10 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
/// <summary>
/// 这里有被禁用的功能第43行
/// </summary>
public class MyServer : MonoBehaviour
{
public static MyServer instance;
public static string version = "1.0";
WebSocketServer wss;
HttpListener httpobj;
[HideInInspector]
public Queue<JObject> reciveData = new Queue<JObject>();
Action<JObject> handleFun_szr = null;
Action<JObject> handleFun_jqr = null;
Action<JObject> handleFun_wrj = null;
Action<JObject> handleFun_other = null;
[HideInInspector]
public ServerHandler handler = null;
public Queue<string> console_log_message = new Queue<string>();
public Queue<string> console_warning_message = new Queue<string>();
public Queue<string> console_error_message = new Queue<string>();
string url = "ws://0.0.0.0:";
private void Awake()
{
instance = this;
}
private void Start()
{
StartWebsocketServer(10088);
//StartWebsocketServer(6001);
//StartHttpServer(10089);
}
private void OnApplicationQuit()
{
StopWebsocketServer(10088);
}
private void OnDestroy()
{
StopWebsocketServer(10088);
}
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);//输出连接状态
}
/// <summary>
/// 启动消息监听
/// </summary>
/// <param name="port"></param>
private void StartWebsocketServer(int port)
{
try
{
string text = url + port;
//string text = "ws://172.16.1.17:10088";
wss = new WebSocketServer(text);
wss.AddWebSocketService<ServerHandler>("/cxx");
wss.KeepClean = false;
wss.Start();
Debug.Log("开始监听,端口:" + text);
//测试输出
//ConsolePanel.ConsoleOutput("开始监听,端口:" + text, "log");
}
catch (Exception ex)
{
Debug.LogError(ex.Message);
//测试输出
//ConsolePanel.ConsoleOutput(ex.Message, "log");
}
}
/// <summary>
/// 关闭消息监听
/// </summary>
public void StopWebsocketServer(int port)
{
if (wss != null)
{
wss.RemoveWebSocketService("/cxx");
wss.Stop();
wss = null;
Debug.Log("关闭监听"+ url+port);
}
}
#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<byte>();
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
/// <summary>
/// 添加数字人消息处理方法
/// </summary>
/// <param name="handlerFun">json消息一定包含以下字段int eventid操作id,string commond 指令 </param>
public void SetHandler_szr(Action<JObject> handlerFun)
{
handleFun_szr = handlerFun;
}
/// <summary>
/// 添加机器人消息处理方法
/// </summary>
/// <param name="handlerFun">json消息一定包含以下字段int eventid操作id,string commond 指令 </param>
public void SetHandler_jqr(Action<JObject> handlerFun)
{
handleFun_jqr = handlerFun;
}
/// <summary>
/// 添加无人机消息处理方法
/// </summary>
/// <param name="handlerFun">json消息一定包含以下字段int eventid操作id,string commond 指令 </param>
public void SetHandler_wrj(Action<JObject> handlerFun)
{
handleFun_wrj = handlerFun;
}
/// <summary>
/// 添加其它类型消息处理方法
/// </summary>
/// <param name="handlerFun">json消息一定包含以下字段int eventid操作id,string commond 指令 </param>
public void SetHandler_other(Action<JObject> handlerFun)
{
handleFun_other = handlerFun;
}
/// <summary>
/// 发送消息, (完全版,可添加自定义字段)
/// </summary>
/// <param name="msg">json格式当回复消息时必须包含以下几个字段int eventid(回复id),ResultState result结果,string msg失败字段</param>
public void SendMsgToSDK(string msg)
{
if (handler != null)
{
handler.SendMsg(msg);
}
}
/// <summary>
/// 发送消息,(简易版,只包含基础字段)
/// </summary>
/// <param name="event_id"></param>
/// <param name="result"></param>
/// <param name="msg"></param>
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 }));
}
}
}
}
/// <summary>
/// 回复的级别
/// </summary>
public enum ResultStatus
{
SUCCESS = 1,
/// <summary>
/// 此操作失败,本次仿真测试继续进行
/// </summary>
FAILED_WARNING = 2,
/// <summary>
/// 此操作失败,本次仿真测试中断
/// </summary>
FAILED_ERROR = 3
}