RemoteService.cs 5.8 KB
using Fleck;
using Newtonsoft.Json;
using OnlineStore.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DeviceLibrary
{
    public static class RemoteService
    {
        /// <summary>
        /// deviceGroupName
        /// </summary>
        static Dictionary<string,IWebSocketConnection> allClients;
        static WebSocketServer server;
        public static void Init() {
            FleckLog.Level = LogLevel.Debug;
            allClients = new Dictionary<string, IWebSocketConnection>();
            server = new WebSocketServer("ws://0.0.0.0:26901");
            server.Start(client =>
            {
                client.OnOpen = () =>
                {
                    var deviceGroupName = client.ConnectionInfo.Path.Substring(1);
                    LogUtil.info($"客户端OnOpen:{deviceGroupName}");
                    lock (allClients)
                    {
                        if (allClients.ContainsKey(deviceGroupName))
                            allClients[deviceGroupName]=client;
                        else
                            allClients.Add(deviceGroupName,client);
                    }
                };
                client.OnClose = () =>
                {
                    var deviceGroupName = client.ConnectionInfo.Path.Substring(1);
                    LogUtil.info($"客户端OnClose:{deviceGroupName}");
                    lock (allClients)
                    {
                        allClients.Remove(deviceGroupName);
                    }
                };
                client.OnMessage = message =>
                {
                    var deviceGroupName = client.ConnectionInfo.Path.Substring(1);
                    //SetINCall(deviceGroupName, JsonConvert.DeserializeObject<RemoteLoad>(message));
                    ProcessMessage(deviceGroupName,message);
                };
            });
        }
        static volatile Dictionary<long, RemoteResult> lastresult = new Dictionary<long, RemoteResult>();
        static void ProcessMessage(string deviceGroupName, string message) {
            bool isok = true;
            long Seq = 1;
            try
            {                
                var remoteLoad = JsonConvert.DeserializeObject<RemoteLoad>(message);
                Seq = remoteLoad.Seq;
                lastresult[Seq] = RemoteResult.None;
                switch (remoteLoad.Action)
                {
                    case "SetTrayRequest":
                        TrayManager.SetTrayRequest(remoteLoad);
                        break;
                    case "TrayInfo":
                        TrayManager.TrayInfo(remoteLoad);
                        break;
                    case "TrayRelease":
                        TrayManager.TrayRelease(remoteLoad);
                        break;
                    case "IsFree":
                        isok = TrayManager.IsFree(remoteLoad);
                        break;
                    case "OK":
                    case "FAIL":
                        lastresult[Seq] = remoteLoad.Action == "OK" ? RemoteResult.True : RemoteResult.False;
                        LogUtil.info("Revice Command Callback:" + remoteLoad.GroupName + " - " + remoteLoad.Action);
                        return;
                    default:
                        break;
                }
            }
            catch(Exception e) {
                isok = false;
                LogUtil.info("Remote process error:"+e.ToString());
            }
            SendResult(deviceGroupName, isok, Seq);
        }
        public static void SendMessage(string deviceGroupName,RemoteLoad message) {
            if (!allClients.ContainsKey(deviceGroupName))
            {
                LogUtil.info($"设备:{deviceGroupName} 不在线");
                return;
            }
            try
            {
                allClients[deviceGroupName].Send(JsonConvert.SerializeObject(message));
            }
            catch (Exception ex){
                LogUtil.info($"设备:{deviceGroupName} 消息发送出错:"+ex.ToString());
            }
        }

        public static RemoteResult SendAndWait(string GroupName, RemoteLoad remoteLoad, int waittime = 3000)
        {
            remoteLoad.GroupName = GroupName;
            if (remoteLoad.RequestLoadInfo != null && string.IsNullOrEmpty(remoteLoad.RequestLoadInfo.DeviceGroupName))
                remoteLoad.RequestLoadInfo.DeviceGroupName = GroupName;
            LogUtil.info($"{GroupName},发送:{remoteLoad.Action},Seq:{remoteLoad.Seq}");
            lastresult[remoteLoad.Seq] = RemoteResult.None;
            SendMessage(GroupName, remoteLoad);
            return WaitResult(GroupName, remoteLoad.Seq,waittime);
        }
        static RemoteResult WaitResult(string GroupName,long seq,int waittime = 3000)
        {
            if (!lastresult.ContainsKey(seq))
                return RemoteResult.Timeout;
            while (lastresult[seq] == RemoteResult.None && waittime > 0)
            {
                System.Threading.Thread.Sleep(50);
                waittime = waittime - 50;
            }
            if (lastresult[seq] == RemoteResult.None)
            {
                LogUtil.info($"等待{GroupName}反馈超时 seq:"+seq);
                lastresult[seq] = RemoteResult.Timeout;
            }
            var result = lastresult[seq];
            lock (lastresult)
            {
                lastresult.Remove(seq);
            }
            return result;
        }
        public static void SendResult(string deviceGroupName, bool result,long Seq)
        {
            RemoteLoad remoteLoad = new RemoteLoad();
            remoteLoad.Seq = Seq;
            remoteLoad.Action = result?"OK":"FAIL";
            remoteLoad.GroupName = deviceGroupName;
            SendMessage(deviceGroupName, remoteLoad);
        }
       
    }

}