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;
///
/// 这里有被禁用的功能,第43行
///
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();
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);//输出连接状态
}
///
/// 启动消息监听
///
///
private void StartWebsocketServer(int port)
{
try
{
string text = url + port;
//string text = "ws://172.16.1.17:10088";
wss = new WebSocketServer(text);
wss.AddWebSocketService("/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");
}
}
///
/// 关闭消息监听
///
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();
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
}