socket 一个websocke对应一个socketclient对象
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Fleck;
namespace DB
{
/// <summary>
/// 客户端网络状态
/// </summary>
///
public enum NetStateEnum
{
[Description("已连接")]
Connected = 1,
[Description("已发送")]
SendData = 2,
[Description("已接收")]
ReceiveData = 3,
[Description("已解析")]
ParseData = 4,
[Description("已离线")]
Disconnected = 5,
[Description("上报超时")]
ReportTimeout = 6
}
/// <summary>
/// 记录每一个Socket连接
/// </summary>
public class SocketConnectionInfo
{
private const int SocketDataBufferSize = 1024;//如果单包数据字节数大于该值则需要加大此值,以免分包
/// <summary>
/// 构造函数将一个套接字和一个客户号码
/// </summary>
/// <param name="socket">套接字</param>
/// <param name="connectionId">设备唯一号</param>
internal SocketConnectionInfo(IWebSocketConnection socket, string connectionId)
{
ConnectionId = connectionId;
CurrentSocket = socket;
DataBuffer = new byte[SocketDataBufferSize];
}
/// <summary>
/// 析构函数
/// </summary>
~SocketConnectionInfo()
{
DataBuffer = null;
CurrentSocket = null;
}
public void Close()
{
if (CurrentSocket != null/* && CurrentSocket.Connected*/)
{
CurrentSocket.Close();
}
}
/// <summary>
/// 客户端的套接字
/// </summary>
public IWebSocketConnection CurrentSocket { get; set; }
/// <summary>
/// 由客户机发送缓冲区来存储数据
/// </summary>
public byte[] DataBuffer { get; set; }
/// <summary>
/// 当前实际接收的数据字节数,与属性DataBuffer结合使用以确定实际接收的数据
/// </summary>
///
public int DataBufferLen { get; set; }
/// <summary>
/// 数据接收时的系统时间
/// </summary>
public DateTime ReceivedTimeFromServer { get; set; }
/// <summary>
/// 最后一次接收的数据里的采集时间
/// </summary>
///
public DateTime ReceivedTimeFromClient { get; set; }
/// <summary>
/// 是否在线
/// </summary>
public bool IsAlive
{
get
{
if (CurrentSocket != null)
{
return CurrentSocket.IsAvailable;
}
else
{
return false;
}
}
}
/// <summary>
/// 用于标识socket连接
/// </summary>
public string ConnectionId { get; set; }
public NetStateEnum NetDataState { get; set; }
public byte[] LastUnParsedBytes { get; set; } // 缓存上次未解析的数据 缓存在每个连接中
public object ParsedEntity { get; set; }
/// <summary>
/// 是否禁用,由用户手工更改。禁用后的连接不处理其收发数据,收到数据直接抛弃。防止客户端数据高频发送无效数据。
/// </summary>
public bool IsDisabled { get; set; }
public bool IsLoggedIn { get; set; } //是否登录成功,只有登录成功的情况下才可以后续通信交互
/// <summary>
/// 当前使用的终端编号,每次通信都有可能修改
/// </summary>
public string CurrentPileCode { get; set; }
public string DeviceId { get; set; }
public string TemporaryHint { get; set; }
public string MessageTypeName { get; internal set; }
}
public class SocketConnectionInfoFactory
{
/// <summary>
/// 所有客户端Socket连接的集合,通过socket对象索引
/// </summary>
private ConcurrentDictionary<IWebSocketConnection, SocketConnectionInfo> dictionary = new ConcurrentDictionary<IWebSocketConnection, SocketConnectionInfo>();
public ConcurrentDictionary<IWebSocketConnection, SocketConnectionInfo> GetItems()
{
return dictionary;
}
public SocketConnectionInfo BindSocketConnectionInfo(IWebSocketConnection socket, string connectionId)
{
SocketConnectionInfo socketConnectionInfo;
if (dictionary.ContainsKey(socket))
{
socketConnectionInfo = dictionary[socket];
}
else
{
socketConnectionInfo = new SocketConnectionInfo(socket, connectionId);
dictionary.TryAdd(socket, socketConnectionInfo);
}
return socketConnectionInfo;
}
public SocketConnectionInfo GetSocketConnectionInfo(string uniqueId)
{
SocketConnectionInfo socketConnectionInfo = null;
foreach (var item in dictionary)
{
if (string.Compare(item.Value?.ConnectionId, uniqueId, true) == 0)
{
if (item.Value.ReceivedTimeFromServer >= socketConnectionInfo?.ReceivedTimeFromServer)
{
Remove(socketConnectionInfo.CurrentSocket);
}
else
{
socketConnectionInfo = item.Value;
}
}
}
return socketConnectionInfo;
}
public void Remove(IWebSocketConnection socket)
{
if (socket != null)
{
dictionary.TryRemove(socket, out SocketConnectionInfo value);
try
{
//判断此连接是否可用
if (socket.IsAvailable)
{
socket.Close();
}
}
catch
{
throw;
}
socket.Close();
value = null;
}
}
public void RemoveAll()
{
foreach (var item in dictionary)
{
item.Value?.Close();
}
dictionary.Clear();
}
public int Count
{
get
{
if (dictionary == null)
{
return 0;
}
return dictionary.Count;
}
}
}
}
调用方式
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DB
{
public class DBHelper
{
private static object obj = new object();
private static SocketConnectionInfoFactory webSocket = null;
public static SocketConnectionInfoFactory GetInstance()
{
if (webSocket == null)
{
lock (obj)
{
if (webSocket == null)
{
webSocket = new SocketConnectionInfoFactory();
}
}
}
return webSocket;
}
}
}
socket 一个websocke对应一个socketclient对象的更多相关文章
- .Net开发笔记(十九) 创建一个可以可视化设计的对象
阅读本篇博客之前需要了解VS窗体设计器的工作原理,详细可参见本系列博客(十).(十一).(十二).必须需要知道的一条结论就是:处于窗体设计器(Form Designer)中的任何组件(包含控件,下同) ...
- threadlocal精髓是为每一个线程保证一个共享对象,保证一个,保证是同一个
threadlocal精髓是为每一个线程保证一个共享对象,保证一个,保证同一个线程中是同一个共享对象. 如果是静态变量是共享的话,那必须同步,否则尽管有副本,还是会出错,故C错
- Tiny Mapper是一个.net平台开源的对象映射组件
NET平台开源项目速览(14)最快的对象映射组件Tiny Mapper 阅读目录 1.Tiny Mapper基本介绍 2.Tiny Mapper 基本使用 3.Tiny Mapper 指定配置使用 ...
- 27、通过visual s'tudio 验证 SOCKET编程:搭建一个TCP服务器
本文就是在windows下进行socket编程,搭建一个TCP客户端. 在visual studio下编程,首先在windows下进行初始化(这点在linux下是不需要的): /* 初始化 Winso ...
- 通过一个uri获取一个Bitmap对象
Android 开发过程中,可能会用到的,通过一个uri获取一个Bitmap对象 private Bitmap getBitmapFromUri(Uri uri){ try { // 读取ur ...
- C#中如果用await关键字来await一个为null的Task对象会抛出异常
await & async模式是C#中一个很重要的特性,可以用来提高异步程序(多线程程序)的执行效率.但是如果尝试用await关键字来await一个为null的Task对象,会导致程序抛出Nu ...
- Object.assign() 从一个或多个源对象复制到目标对象
Object.assign()方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象.它将返回目标对象. 1.语法: Object.assign(target, ... , sources) 参 ...
- 创建一个doc对象时候 如果读取了一个已存在的xml对象时候 该xml对象的结构已存在doc中 当改变该doc结构时候 不需要创建新的doc对象
创建一个doc对象时候 如果读取了一个已存在的xml对象时候 该xml对象的结构已存在doc中 当改变该doc结构时候不 需要创建新的doc对象 直接添加即可 他会同步过去
- iter创建一个可以被迭代的对象
#!/usr/bin/env python obj = iter([11,22,33,44]) #iter 创建一个可以被迭代的对象 print(obj) r1 = next(obj) print(r ...
随机推荐
- 2019杭电多校第七场 HDU - 6656 Kejin Player——概率&&期望
题意 总共有 $n$ 层楼,在第 $i$ 层花费 $a_i$ 的代价,有 $pi$ 的概率到 $i+1$ 层,否则到 $x_i$($x_i \leq 1$) 层.接下来有 $q$ 次询问,每次询问 $ ...
- vue app.xxx.js 较大问题
线上build之后发现app.XXX.js 文件特别大. 包我都改为cdn了 其他空间就是路由改为懒加载了. { path: '/a/b', name: 'ab', component: () =&g ...
- 定时器 间隔调用setInterval
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 使用$.getJSON("xx.json" ,function(data){ console.logy(data); })在本地获取 json数据
使用 $.getJSON() 在本地获取 json数据 默认在谷歌,火狐等其他浏览器,不允许在本地获取服务器数据 所以不能在本地中使用 但是可以IE 11 中又可以使用,所以,测试时建议在IE浏览器 ...
- window.external 是调用外部方法
ie中,window.external 是调用外部方法,比如,是在 winform 中的 webbrower 中使用 window.external.SendData(),那么,SendData() ...
- PHP基础语法之 位运算
写了几年PHP的人都好奇说,没有用过位运算符.所以,此处你看二进制看的头晕,就去T¥M¥D吧. 位运算符基本不用,我们也将这个知识设置为了解级别.位运算符的知识点,你不想学习也可以.等以后用到位运算的 ...
- 基础 | BIO、NIO与AIO
本文链接:https://blog.csdn.net/bingbeichen/article/details/83617163 Java中的IO部分比较复杂,具体可参看书籍<Java NIO&g ...
- PHP全栈学习笔记29
前言 这一章主要讲一讲PHP的背景,优势,PHP的环境搭建,书写和调式简单的PHP代码,如何解决简单的PHP错误等. 目录结构 PHP简介 PHP是面向对象,指令式编程,设计者是 拉斯姆斯·勒多夫 出 ...
- Python基础之给函数增加元信息
1. 参数注解 当写好一个函数以后,想为这个函数的参数添加一些额外的信息,这样的话,其他的使用者就可以清楚的知道这个函数应该怎么使用,这个时候可以使用函数参数注解. 函数参数注解能提示程序员应该怎样正 ...
- NNDL练习——Numpy的简单使用
总结自nndl_exercise Numpy导入 import numpy as np 数组/矩阵的创建 a=np.array([1,2,3]) b=np.array([[1,2],[3,4]]) c ...