Beispiel #1
0
        //这必须是个同步函数,因为他将被不能定义为异步函数的地方调用。
        public static void Dispose(TimeSpan timeSpan = default(TimeSpan))
        {
            //正常退出时,如果还有正在进行的会话,则将这些会话序列化起来。
            foreach (Conversation conv in Conversations.Values)
            {
                //TODO 新特性 每个会话还要设置超时。而且信息是明文的。这需要认真考虑。
            }

            //给每个已经连接的设备发Offline消息,广播下线消息不一定正确。因为不能保证所有人都能收到广播,建立连接的方式不一定只是局域网。
            foreach (var device in Devices)
            {
                if (device.State == DeviceState.Connected)
                {
                    device.Disconnect();
                }
                device.NotifyImOffline();
            }

            Util.WaitAnySync(
                () => Devices.Any(d => d.State != DeviceState.Connected),
                TimeSpan.FromMilliseconds(300), 50);


            Stop();
            _instance._discoverer.Dispose();
            _instance._channelManager.Dispose();
            _instance._httpServer.Dispose();
            _instance._httpServer = null;
        }
Beispiel #2
0
        internal TcpChannel(TcpClient client)
        {
            Util.CheckParam(client != null);
            this._client = client;
            var iep = client?.Client.RemoteEndPoint as IPEndPoint;

            RemoteIP = iep?.Address.ToString();

#pragma warning disable 1998
            _readTask = new TaskWrapper("Channel Listener", ReadWorker_DoWork, TaskCreationOptions.LongRunning);
#pragma warning restore 1998
            _readTask.Start();
        }
Beispiel #3
0
        public void StartImpl()
        {
            Util.Check(LocalDevice != null, "Local Device Must be set before start");
            if (_isRunning)
            {
                return;
            }

            _isRunning = true;
            _discoverer.StartListen();
            _discoverer.StartBroadcast();
            _channelManager.Start();


            Env.Logger.Log("SuperDriveCore Started", nameof(SuperDriveCore));
        }
Beispiel #4
0
        private byte[] Receive(int length, out int count)
        {
            Util.Check(length > 0);
            count = 0;
            var bytes  = new byte[length];
            var socket = _client.Client;


            while (count < length && socket != null)
            {
                count += socket.Receive(bytes, count, length - count, SocketFlags.None);
                if (count == 0)
                {
                    //Thread.Sleep(200);
                    //throw new SocketException(); //TODO 这个地方再仔细研究一下。为什么会收到0?到底能不能重用?socket receive 可以收到0字节,error = connectionreset.
                }
            }
            return(bytes);
        }
Beispiel #5
0
        /// <summary>
        /// 如果已经知道一个设备,则更新已有设备的信息。如果是一个新设备,把它添加到列表中。
        ///
        /// 改这个要慎重,它被LANDiscoverer调用,还被Device的Connect调用。
        /// </summary>
        /// <param name="device"></param>
        /// <param name="needMerge"></param>
        /// <returns></returns>

        public static Device AddOrUpdateDevice(Device device, bool needMerge = true)
        {
            //检查这个Device是否已知。
            if (device == null)
            {
                return(null);
            }

            Util.Check(!string.IsNullOrEmpty(device.Id));
            if (device.Id == LocalDevice.Id)
            {
                return(null);
            }

            var existingDevice = Devices.FirstOrDefault(o => o.Id == device.Id);

            if (existingDevice == null)
            {
                _instance.DevicesInternal.Add(device);
                device.IsFirstSeen = true;
                _instance.DeviceDiscovered?.Invoke(device);
            }
            else
            {
                //如果这个设备原来已经存在了,那么其实应该返回原来的设备,只是需要将新发现的不同的地方复制到原来的设备上
                //各事件都是绑定到原来的设备的。
                if (needMerge)
                {
                    existingDevice.CopyFrom(device);
                }
                //不管是否Merge,都要修改IP。
                existingDevice.DefaultIp     = device.DefaultIp;
                existingDevice.DiscoveryType = device.DiscoveryType;                 //是只记录一种发现方式,还是可以记录多种?
                device             = existingDevice;
                device.IsFirstSeen = false;
            }
            device.LastUpdateTime = Environment.TickCount;
            return(device);
        }
Beispiel #6
0
        public static Config Load(Env container, string fileName)
        {
            Util.Check(!string.IsNullOrEmpty(fileName), "必须指定配置文件路径。");

            bool   dirtdy = false;
            Config config = new Config();

            config.configFileName = fileName;

            string json = "";

            try
            {
                json = File.ReadAllText(fileName, Encoding.UTF8);
                JsonConvert.PopulateObject(json, config);
            }
            catch (Exception e)
            {
                dirtdy = true;
            }

            //检查反序列化后各个成员是否正确,如果不正确,配置默认值。
            //TODO DeviceInfo 序列化说明

            if (config.LocalDevice == null)
            {
                dirtdy = true;
                var device = new Device()
                {
                    Avatar     = Avatar.Facebook,
                    Name       = Env.UserName,   // Environment.UserName, //TODO
                    DeviceName = Env.DeviceName, // Environment.MachineName,
                    Version    = "1.0",
                    DeviceType = DeviceType.PC
                };


                if (string.IsNullOrEmpty(device.Name) || device.Name.ToLower().Equals("somebody"))
                {
                    device.Name = device.DeviceName;
                }


                config.LocalDevice = device;
            }
            if (string.IsNullOrEmpty(config.LocalDevice.DeviceName))
            {
                config.LocalDevice.DeviceName = Env.DeviceName;
            }
            if (config.LocalDevice.Id == null)
            {
                config.LocalDevice.Id = StringHelper.NewRandomGUID();
                dirtdy = true;
            }
            if (config.LogLevel == null)
            {
                config.LogLevel = LogLevel.Error;
                dirtdy          = true;
            }
            if (config.TrustDevices == null)
            {
                config.TrustDevices = new List <Device>();
                dirtdy = true;
            }

            if (string.IsNullOrEmpty(config.DefaultDir) || !Directory.Exists(config.DefaultDir))
            {
                config.DefaultDir = Env.FileSystem.DefaultDir;
                dirtdy            = true;
            }

            if (dirtdy)
            {
                config.Save();
            }
            return(config);
        }