| | |
| | | using ServiceStack.Configuration; |
| | | using ServiceStack; |
| | | using Spectre.Console; |
| | | using System.Net.WebSockets; |
| | | using System.Net; |
| | | using System.Threading; |
| | | using System.IO; |
| | | |
| | | namespace GZ.Projects.AuxAllWCS |
| | | { |
| | |
| | | } |
| | | |
| | | // æ§è¡å§æ |
| | | if (methodName != "TaskEverythingRun") |
| | | return null; |
| | | return methodDelegate.DynamicInvoke(args); |
| | | } |
| | | |
| | |
| | | public string WriteLine(string value = "") |
| | | { |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | // å¨è¿éæ¦æªå¤çè¾åº |
| | |
| | | { |
| | | if (tag.wxr1.R44 && !tag.wxr1.R44_LAST && tag.wxr1.R10) |
| | | { |
| | | if (TcpServer.TrayIps.TryGetValue(VERX.deviceNo[0], out string traycode)) |
| | | if (TcpServer.TrayIps.TryGetValue(VERX.deviceNo[0], out string traycode) && !string.IsNullOrEmpty(traycode.Trim())) |
| | | { |
| | | var str = Settings.apiHelper.Post(Settings.WMSbaseUrl + "mom-basic/dataTransmission/json/service/200", JsonConvert.SerializeObject(new |
| | | { |
| | |
| | | RedisHelper.Add($"ç»´å¸å°æè1.R10_LAST", "false", out string msg); |
| | | } |
| | | else |
| | | if (TcpServer.TrayIps.TryGetValue(VERX.deviceNo[0], out string traycode)) |
| | | if (TcpServer.TrayIps.TryGetValue(VERX.deviceNo[0], out string traycode) && !string.IsNullOrEmpty(traycode.Trim())) |
| | | { |
| | | //䏿¥æ ¡éªã |
| | | ///var str = Settings.apiHelper.Post(Settings.MESbaseUrl + "mom-basic/dataTransmission/json/service/202", requestJson); |
| | |
| | | { |
| | | if (tag.wxr1.R46 && !tag.wxr1.R46_LAST && tag.wxr1.R11) |
| | | { |
| | | if (TcpServer.TrayIps.TryGetValue(VERX.deviceNo[1], out string traycode)) |
| | | if (TcpServer.TrayIps.TryGetValue(VERX.deviceNo[1], out string traycode) && !string.IsNullOrEmpty(traycode.Trim())) |
| | | { |
| | | var str = Settings.apiHelper.Post(Settings.WMSbaseUrl + "mom-basic/dataTransmission/json/service/200", JsonConvert.SerializeObject(new |
| | | { |
| | |
| | | RedisHelper.Add($"ç»´å¸å°æè1.R11_LAST", "false", out string msg); |
| | | } |
| | | else |
| | | if (TcpServer.TrayIps.TryGetValue(VERX.deviceNo[1], out string traycode)) |
| | | if (TcpServer.TrayIps.TryGetValue(VERX.deviceNo[1], out string traycode) && !string.IsNullOrEmpty(traycode.Trim())) |
| | | { |
| | | //䏿¥æ ¡éªã |
| | | ///var str = Settings.apiHelper.Post(Settings.MESbaseUrl + "mom-basic/dataTransmission/json/service/202", requestJson); |
| | |
| | | { |
| | | if (tag.wxr2.R44 && !tag.wxr2.R44_LAST && tag.wxr2.R10) |
| | | { |
| | | if (TcpServer.TrayIps.TryGetValue(VERX.deviceNo[0], out string traycode)) |
| | | if (TcpServer.TrayIps.TryGetValue(VERX.deviceNo[0], out string traycode) && !string.IsNullOrEmpty(traycode.Trim())) |
| | | { |
| | | var str = Settings.apiHelper.Post(Settings.WMSbaseUrl + "mom-basic/dataTransmission/json/service/200", JsonConvert.SerializeObject(new |
| | | { |
| | |
| | | RedisHelper.Add($"ç»´å¸å°æè2.R10_LAST", "false", out string msg); |
| | | } |
| | | else |
| | | if (TcpServer.TrayIps.TryGetValue(VERX.deviceNo[0], out string traycode)) |
| | | if (TcpServer.TrayIps.TryGetValue(VERX.deviceNo[0], out string traycode) && !string.IsNullOrEmpty(traycode.Trim())) |
| | | { |
| | | //䏿¥æ ¡éªã |
| | | ///var str = Settings.apiHelper.Post(Settings.MESbaseUrl + "mom-basic/dataTransmission/json/service/202", requestJson); |
| | |
| | | { |
| | | if (tag.wxr2.R46 && !tag.wxr2.R46_LAST && tag.wxr2.R11) |
| | | { |
| | | if (TcpServer.TrayIps.TryGetValue(VERX.deviceNo[1], out string traycode)) |
| | | if (TcpServer.TrayIps.TryGetValue(VERX.deviceNo[1], out string traycode) && !string.IsNullOrEmpty(traycode.Trim())) |
| | | { |
| | | var str = Settings.apiHelper.Post(Settings.WMSbaseUrl + "mom-basic/dataTransmission/json/service/200", JsonConvert.SerializeObject(new |
| | | { |
| | |
| | | } |
| | | else |
| | | { |
| | | //LogHelper.Info($"Threadwxr2R æçæ¾ç½®ä¿¡å·1ãã -{tag.wxr2.R11_LAST}"); |
| | | if (tag.wxr2.R11_LAST) //æçæ¾ç½®ä¿¡å·ãã |
| | | { |
| | | //LogHelper.Info($"Threadwxr2R æçæ¾ç½®ä¿¡å·1ãã -{tag.wxr2.R11}"); |
| | | if (tag.wxr2.R11) |
| | | { |
| | | //tag.wxr2.R11_LAST = false; |
| | | RedisHelper.Add($"ç»´å¸å°æè2.R11_LAST", "false", out string msg); |
| | | } |
| | | else |
| | | if (TcpServer.TrayIps.TryGetValue(VERX.deviceNo[1], out string traycode)) |
| | | if (TcpServer.TrayIps.TryGetValue(VERX.deviceNo[1], out string traycode) && !string.IsNullOrEmpty(traycode.Trim())) |
| | | { |
| | | LogHelper.Info($"Threadwxr2R 䏿¥æ ¡éª>{traycode}"); |
| | | //䏿¥æ ¡éªã |
| | | ///var str = Settings.apiHelper.Post(Settings.MESbaseUrl + "mom-basic/dataTransmission/json/service/202", requestJson); |
| | | var str = Settings.apiHelper.Post(Settings.WMSbaseUrl + "mom-basic/dataTransmission/json/service/202", JsonConvert.SerializeObject(new |
| | |
| | | //æ¥è¦ã |
| | | } |
| | | } |
| | | else { TcpServer.TcpServerSend(VERX.deviceNo[1], GZ.Device.PLC.PlcHelper.Hex2Bin("544F4E")); } |
| | | else |
| | | { |
| | | LogHelper.Info($"Threadwxr2Rãã -åéæ«ç "); |
| | | TcpServer.TcpServerSend(VERX.deviceNo[1], GZ.Device.PLC.PlcHelper.Hex2Bin("544F4E")); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | Console.WriteLine($"Threadwxr2R ç»´å¸å°2 å³ è®¾å¤æªæ¾å°ã =================> "); |
| | | } |
| | | } |
| | | |
| | |
| | | return new HkReturnResult { reqCode = model.reqCode, code = 0 }; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | public void TaskEverythingRun() |
| | | { |
| | | var host = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()); |
| | | foreach (var ip in host.AddressList) |
| | | { |
| | | if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) |
| | | { |
| | | Console.WriteLine($"ip= {ip.ToString()}"); |
| | | new HttpServer(ip.ToString()).HttpServerRun(); |
| | | new TcpServer(ip.ToString()); |
| | | var server = new EnhancedWebSocketServer($"http://{ip.ToString()}:8809/").StartAsync(); |
| | | //var client = new WebSocketClient($"http://{ip.ToString()}:8809/").ConnectAsync(); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | |
| | | |
| | | } |
| | | |
| | | public class HttpServer |
| | | { |
| | | System.Net.HttpListener HttpSvcHost = null; |
| | | |
| | | private readonly string _listenerPrefix = ""; |
| | | public HttpServer(string ip) |
| | | { |
| | | _listenerPrefix = ip; |
| | | } |
| | | public void HttpServerRun() |
| | | { |
| | | HttpSvcHost = new System.Net.HttpListener(); |
| | | HttpSvcHost.AuthenticationSchemes = System.Net.AuthenticationSchemes.Anonymous; |
| | | HttpSvcHost.Prefixes.Add($"http://{_listenerPrefix}:8808/"); |
| | | HttpSvcHost.Start(); |
| | | HttpSvcHost.BeginGetContext(HttpSvcListenerCallback, null); |
| | | } |
| | | |
| | | |
| | | private async void HttpSvcListenerCallback(IAsyncResult ar) |
| | | { |
| | | System.Net.HttpListenerContext context = null; |
| | | var data = DateTime.Now; |
| | | string apth = ""; |
| | | try |
| | | { |
| | | HttpSvcHost.BeginGetContext(HttpSvcListenerCallback, null); |
| | | context = HttpSvcHost.EndGetContext(ar); |
| | | System.Net.HttpListenerRequest request = context.Request; |
| | | System.Net.HttpListenerResponse response = context.Response; |
| | | |
| | | using (var reader = new System.IO.StreamReader(request.InputStream, System.Text.Encoding.UTF8)) |
| | | { |
| | | string requestJson = reader.ReadToEnd(); |
| | | System.Net.HttpStatusCode statusCode = 0; |
| | | apth = request.Url.AbsolutePath; |
| | | string respstr = HttpSvcListenerCallback_he(request.HttpMethod, request.Url.AbsolutePath, requestJson, out statusCode); |
| | | string logContent = ""; |
| | | logContent += $"\r\n[{request.HttpMethod}]{request.Url.AbsolutePath}"; |
| | | logContent += $"\r\n[request]{requestJson}"; |
| | | logContent += $"\r\n[response]{respstr}"; |
| | | _ = Task.Run(() => |
| | | { |
| | | Conn.é»è®¤æ¥å¿?.Info(logContent); |
| | | }); |
| | | byte[] bytstr = Encoding.UTF8.GetBytes(respstr); |
| | | response.StatusCode = (int)statusCode; |
| | | response.SendChunked = false; |
| | | response.ContentLength64 = bytstr.Length; |
| | | //response.OutputStream.Write(bytstr, 0, bytstr.Length); |
| | | if (request.Url.AbsolutePath.ToLower().Contains(".js")) |
| | | response.ContentType = "application/javascript"; |
| | | else if (request.Url.AbsolutePath.ToLower().Contains(".svg")) |
| | | response.ContentType = "image/svg+xml"; |
| | | // 弿¥åå
¥ååº |
| | | await response.OutputStream.WriteAsync(bytstr, 0, bytstr.Length); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _ = Task.Run(() => |
| | | { |
| | | Conn.é»è®¤æ¥å¿.Error(ex.ToString()); |
| | | }); |
| | | } |
| | | finally |
| | | { |
| | | context?.Response.Close(); |
| | | Console.WriteLine(apth + "<<>>" + DateTime.Now.Subtract(data).TotalMilliseconds); |
| | | } |
| | | } |
| | | private System.String HttpSvcListenerCallback_he(System.String method, System.String path, System.String requestJson, out System.Net.HttpStatusCode statusCode) |
| | | { |
| | | try |
| | | { |
| | | switch (method) |
| | | { |
| | | case "POST": |
| | | { |
| | | switch (path) |
| | | { |
| | | case "/agv/agvCallbackService/agvCallback": |
| | | { |
| | | statusCode = System.Net.HttpStatusCode.OK; |
| | | |
| | | LogHelper.Info("ExecuteState Request-haikangï¼" + requestJson); |
| | | var model = JsonConvert.DeserializeObject<HaiKangOrderInfo>(requestJson); |
| | | AutoThread.Instance.OperateHKTaskStatus(model); |
| | | return JsonConvert.SerializeObject(new HkReturnResult { reqCode = model.reqCode }); |
| | | } |
| | | case "/api/Wcs/CreateTask": |
| | | { |
| | | statusCode = System.Net.HttpStatusCode.OK; |
| | | |
| | | LogHelper.Info("/api/Wcs/CreateTaskï¼" + requestJson); |
| | | var model = JsonConvert.DeserializeObject<ToWMSMES.CreateTask>(requestJson); |
| | | var res = ToWMSMES.CreateTask.CreatemesTask(model); |
| | | return JsonConvert.SerializeObject(res); |
| | | } |
| | | case "/api/Wcs/TestRequestTask": |
| | | { |
| | | statusCode = System.Net.HttpStatusCode.OK; |
| | | LogHelper.Info("/api/Wcs/TestRequestTaskï¼" + requestJson); |
| | | var str = Settings.apiHelper.Post(Settings.WMSbaseUrl + "mom-basic/dataTransmission/json/service/200", requestJson); |
| | | return str; |
| | | } |
| | | case "/api/Wcs/updateStatus": |
| | | { |
| | | statusCode = System.Net.HttpStatusCode.OK; |
| | | LogHelper.Info("/api/Wcs/updateStatusï¼" + requestJson); |
| | | var str = Settings.apiHelper.Post(Settings.WMSbaseUrl + "mom-basic/dataTransmission/json/service/201", requestJson); |
| | | return str; |
| | | } |
| | | case "/api/Wcs/toMes": |
| | | { |
| | | statusCode = System.Net.HttpStatusCode.OK; |
| | | |
| | | LogHelper.Info("/api/Wcs/toMesï¼" + requestJson); |
| | | var str = Settings.apiHelper.Post(Settings.MESbaseUrl + "mom-basic/dataTransmission/json/service/202", requestJson); |
| | | return str; |
| | | } |
| | | case "/api/Wcs/CreatePointTask": |
| | | { |
| | | statusCode = System.Net.HttpStatusCode.OK; |
| | | |
| | | LogHelper.Info("/api/Wcs/CreatepointTaskï¼" + requestJson); |
| | | var model = JsonConvert.DeserializeObject<ToWMSMES.CreateTask>(requestJson); |
| | | var res = ToWMSMES.CreateTask.CreatePointTask(model); |
| | | return JsonConvert.SerializeObject(res); |
| | | } |
| | | } |
| | | break; |
| | | } |
| | | case "GET": |
| | | { |
| | | switch (path) |
| | | { |
| | | case var _ when System.Text.RegularExpressions.Regex.IsMatch(path, @"\.(html|ico|js|css)(\?.*)?$", System.Text.RegularExpressions.RegexOptions.IgnoreCase): |
| | | { |
| | | statusCode = System.Net.HttpStatusCode.OK; |
| | | // å¤å¶å°case ä¸ |
| | | //var _ when System.Text.RegularExpressions.Regex.IsMatch(path, @"\.(html|ico|js|css)(\?.*)?$", System.Text.RegularExpressions.RegexOptions.IgnoreCase) |
| | | var filePath = /*Directory.GetCurrentDirectory() + "\\Static" + "\\" + path.Substring(1);*/System.IO.Path.Combine(Directory.GetCurrentDirectory() + "\\Static", path.Substring(1)); |
| | | return File.ReadAllText(filePath); |
| | | } |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | statusCode = System.Net.HttpStatusCode.NotFound; |
| | | return ""; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Conn.é»è®¤æ¥å¿.Error(ex.ToString()); |
| | | statusCode = System.Net.HttpStatusCode.InternalServerError; |
| | | return ""; |
| | | } |
| | | } |
| | | } |
| | | |
| | | class EnhancedWebSocketServer |
| | | { |
| | | private HttpListener _listener; |
| | | private readonly string _listenerPrefix; |
| | | private readonly ConcurrentDictionary<Guid, WebSocket> _connections = new ConcurrentDictionary<Guid, WebSocket>(); |
| | | private CancellationTokenSource _cts = new CancellationTokenSource(); |
| | | |
| | | public EnhancedWebSocketServer(string url) |
| | | { |
| | | _listenerPrefix = url; |
| | | } |
| | | |
| | | public async Task StartAsync() |
| | | { |
| | | try |
| | | { |
| | | _listener = new HttpListener(); |
| | | _listener.Prefixes.Add(_listenerPrefix); |
| | | _listener.Start(); |
| | | Console.WriteLine($"WebSocketæå¡å¨å·²å¯å¨ï¼çå¬ {_listenerPrefix}"); |
| | | while (!_cts.IsCancellationRequested) |
| | | { |
| | | HttpListenerContext context = await _listener.GetContextAsync(); |
| | | if (context.Request.IsWebSocketRequest) |
| | | { |
| | | var wsContext = await context.AcceptWebSocketAsync(null); |
| | | var connectionId = Guid.NewGuid(); |
| | | _connections[connectionId] = wsContext.WebSocket; |
| | | _ = HandleConnectionAsync(connectionId, wsContext.WebSocket, _cts.Token); |
| | | } |
| | | else |
| | | { |
| | | context.Response.StatusCode = 400; |
| | | context.Response.Close(); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception ex) when (ex is HttpListenerException || ex is ObjectDisposedException) |
| | | { |
| | | // æå¡å¨åæ¢æ¶çæ£å¸¸å¼å¸¸ |
| | | Console.WriteLine("æå¡å¨æ£å¨åæ¢..."); |
| | | } |
| | | } |
| | | |
| | | private async Task HandleConnectionAsync(Guid connectionId, WebSocket webSocket, CancellationToken ct) |
| | | { |
| | | var buffer = new byte[1024 * 4]; |
| | | try |
| | | { |
| | | while (webSocket.State == WebSocketState.Open && !ct.IsCancellationRequested) |
| | | { |
| | | var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), ct); |
| | | |
| | | if (result.MessageType == WebSocketMessageType.Close) |
| | | { |
| | | await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "客æ·ç«¯å
³éè¿æ¥", ct); |
| | | break; |
| | | } |
| | | |
| | | string message = System.Text.Encoding.UTF8.GetString(buffer, 0, result.Count); |
| | | Console.WriteLine($"è¿æ¥ {connectionId} æ¶å°æ¶æ¯: {message}"); |
| | | |
| | | // å¹¿ææ¶æ¯ç»ææå®¢æ·ç«¯ |
| | | await BroadcastMessageAsync($"客æ·ç«¯ {connectionId} 说: {message}"); |
| | | } |
| | | } |
| | | catch (WebSocketException ex) |
| | | { |
| | | Console.WriteLine($"è¿æ¥ {connectionId} é误: {ex.WebSocketErrorCode} - {ex.Message}"); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Console.WriteLine($"å¤çè¿æ¥ {connectionId} æ¶åºé: {ex.Message}"); |
| | | } |
| | | finally |
| | | { |
| | | _connections.TryRemove(connectionId, out _); |
| | | webSocket?.Dispose(); |
| | | Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")} è¿æ¥ {connectionId} å·²å
³é"); |
| | | } |
| | | } |
| | | |
| | | public async Task BroadcastMessageAsync(string message) |
| | | { |
| | | var buffer = System.Text.Encoding.UTF8.GetBytes(message); |
| | | foreach (var connection in _connections) |
| | | { |
| | | if (connection.Value.State == WebSocketState.Open) |
| | | { |
| | | try |
| | | { |
| | | await connection.Value.SendAsync( |
| | | new ArraySegment<byte>(buffer), |
| | | WebSocketMessageType.Text, |
| | | true, |
| | | CancellationToken.None); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Console.WriteLine($"å¹¿ææ¶æ¯å°è¿æ¥ {connection.Key} 失败: {ex.Message}"); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | public async Task StopAsync() |
| | | { |
| | | _cts.Cancel(); |
| | | |
| | | // å
³éææè¿æ¥ |
| | | foreach (var connection in _connections) |
| | | { |
| | | try |
| | | { |
| | | if (connection.Value.State == WebSocketState.Open) |
| | | { |
| | | await connection.Value.CloseAsync( |
| | | WebSocketCloseStatus.NormalClosure, |
| | | "æå¡å¨å
³é", |
| | | CancellationToken.None); |
| | | } |
| | | connection.Value.Dispose(); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Console.WriteLine($"å
³éè¿æ¥ {connection.Key} æ¶åºé: {ex.Message}"); |
| | | } |
| | | } |
| | | |
| | | _listener?.Stop(); |
| | | _listener?.Close(); |
| | | Console.WriteLine("WebSocketæå¡å¨å·²åæ¢"); |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | internal class WebSocketClient |
| | | { |
| | | private ClientWebSocket _webSocket = new ClientWebSocket(); |
| | | private readonly Uri _serverUri; |
| | | |
| | | public WebSocketClient(string serverUrl) |
| | | { |
| | | _serverUri = new Uri(serverUrl); |
| | | } |
| | | |
| | | public async Task ConnectAsync() |
| | | { |
| | | try |
| | | { |
| | | await _webSocket.ConnectAsync(_serverUri, CancellationToken.None); |
| | | Console.WriteLine("å·²è¿æ¥å°WebSocketæå¡å¨"); |
| | | |
| | | // å¯å¨æ¥æ¶æ¶æ¯ä»»å¡ |
| | | _ = ReceiveMessagesAsync(); |
| | | |
| | | // åéæµè¯æ¶æ¯ |
| | | await SendMessageAsync("Hello, Server!"); |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Console.WriteLine($"è¿æ¥å¤±è´¥: {ex.Message}"); |
| | | } |
| | | } |
| | | |
| | | private async Task ReceiveMessagesAsync() |
| | | { |
| | | var buffer = new byte[1024]; |
| | | try |
| | | { |
| | | while (_webSocket.State == WebSocketState.Open) |
| | | { |
| | | var result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); |
| | | if (result.MessageType == WebSocketMessageType.Close) |
| | | { |
| | | await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None); |
| | | Console.WriteLine("æå¡å¨å
³éäºè¿æ¥"); |
| | | break; |
| | | } |
| | | |
| | | string message = Encoding.UTF8.GetString(buffer, 0, result.Count); |
| | | Console.WriteLine($"æ¶å°æå¡å¨æ¶æ¯: {message}"); |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | Console.WriteLine($"æ¥æ¶æ¶æ¯æ¶åºé: {ex.Message}"); |
| | | } |
| | | } |
| | | |
| | | public async Task SendMessageAsync(string message) |
| | | { |
| | | if (_webSocket.State != WebSocketState.Open) |
| | | { |
| | | Console.WriteLine("WebSocketæªè¿æ¥ï¼æ æ³åéæ¶æ¯"); |
| | | return; |
| | | } |
| | | |
| | | byte[] buffer = Encoding.UTF8.GetBytes(message); |
| | | await _webSocket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None); |
| | | } |
| | | |
| | | public async Task DisconnectAsync() |
| | | { |
| | | if (_webSocket.State == WebSocketState.Open) |
| | | { |
| | | await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "客æ·ç«¯å
³éè¿æ¥", CancellationToken.None); |
| | | } |
| | | _webSocket.Dispose(); |
| | | Console.WriteLine("å·²æå¼WebSocketè¿æ¥"); |
| | | } |
| | | } |
| | | |
| | | |
| | | class Messss |
| | | { |
| | | public bool success { get; set; } |