//这必须是个同步函数,因为他将被不能定义为异步函数的地方调用。 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; }
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(); }
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)); }
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); }
/// <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); }
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); }