340 lines
10 KiB
C#
340 lines
10 KiB
C#
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
|
||
}
|