windows环境下使用的即时通信基础应用,服务端使用superwebsocket框架,客户端使用websocket,方便BS、CS环境下使用。本实例做为我的备忘录,只是简单应用,不对通信原理做分析,老鸟请忽略。。。
一、服务器端
添加引用(打开NuGet),安装SuperWebSocket包,系统自动下载依赖项Log4net(日志记录包),安装完成。
logger.config配置文件内容(XML文档)。如果不使用日志,这一步可以跳过
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,HMmlg.Utils"/>
</configSections>
<log4net>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="logs\log"/>
<appendToFile value="true"/>
<rollingStyle value="Date"/>
<datePattern value="yyyyMMdd'.txt'"/>
<staticLogFileName value="false"/>
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n"/>
</layout>
</appender>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n"/>
</layout>
</appender>
<root>
<!--<level value="ERROR"/>-->
<level value="ALL"/>
<appender-ref ref="RollingLogFileAppender"/>
<appender-ref ref="ConsoleAppender"/>
</root>
</log4net>
</configuration>
将logger.config文件放到运行目录下。
程序中引用log4net配置文件,好了这步就算完了。
string path = AppDomain.CurrentDomain.BaseDirectory + "logger.config";
log4net.Config.XmlConfigurator.Configure(new FileInfo(path));
正式进入SuperWebSocket应用
首先添加一个类:serviceCls.cs
//创建服务端对象
public WebSocketServer appServer = new WebSocketServer();
//初始化日志对象
public ILog log = LogManager.GetLogger("即时通讯服务");
//已连接客户端列表
public IndexForUser UserList = new IndexForUser();
同时定义一个用户身份信息类User.cs,再建一个用户索引器类IndexForUser.cs.在索引器中记录所有已连接客户端,以方便对客户操作。
//客户端用户信息类
public class User
{
//socket连接标识ID
public string sessionID { get; set; }
//安全标识ID
public string SN { get; set; }
public string Name { get; set; }
public string IP { get; set; }
public object Tag { get; set; }
public WebSocketSession Session { get; set; }
public User(string ID)
{
this.sessionID = ID;
}
public User(string sessionid, WebSocketSession session, string project, string role, string phone)
{
this.sessionID = sessionid;
this.Session = session;
}
}
//声明一个客户端用户的索引器
public class IndexForUser
{
private ArrayList ArrLst;//用于存放User类
public IndexForUser()
{
ArrLst = new ArrayList();
}
//声明一个索引器:以编号查找SN
public string this[string sessionid, WebSocketSession session, string project, string role]
{
get
{
foreach (User en in ArrLst)
{
if (en.sessionID == sessionid && en.Session == session && en.Project == project && en.Role == role)
{
return en.SN;
}
}
return null;
}
set
{
//new关键字:C#规定,实例化一个类或者调用类的构造函数时,必须使用new关键
ArrLst.Add(new User(sessionid, session, project, role, value));
}
}
public User this[string id]
{
get
{
foreach (User en in ArrLst)
{
if (en.sessionID == id)
{
return en;
}
}
return null;
}
}
}
建立一个方法Start()来启动服务,End()断开客户端,SendMsg(WebSocketSession session, string msg)向客户端发送消息,方便调用.端口号和日志根据情况而定,启动成功后,同时实现三个事件:NewSessionConnected,NewMessageReceived,SessionClosed。这三个事件是对客户端连接成功、接收消息、客户端断开做处理。
//启动websocket服务
public void Start()
{
log.Debug("SuperWebSocket(0.8).Source服务器 start the WebSocketServer!");
if (!appServer.Setup(2000))
{
log.Error("Failed to setup!");
return;
}
appServer.NewSessionConnected += new SessionHandler<WebSocketSession>(appServer_NewClientConnected);
appServer.NewMessageReceived += new SessionHandler<WebSocketSession, string>(appServer_NewMessageReceived);
appServer.SessionClosed += new SessionHandler<WebSocketSession, CloseReason>(appServer_SessionClosed);
if (!appServer.Start())
{
log.Error("Failed to start!");
return;
}
log.Info("通讯服务器启动成功!");
}
//停止websocket服务
public void End()
{
appServer.Stop();
}
//发送消息方法
private void SendMsg(WebSocketSession session, string msg)
{
session.Send(msg);
}
下面的事件中没有具体操作内容,视情况而定,点到为止。
private void appServer_NewClientConnected(WebSocketSession session)
{
//客户端连接成功事件,在此事件中可以开启一个定时器,在规定时间内验证客户端身份,比如3秒钟后验证是否上传基本身份信息,如果与数据库中ID做对比,如果不存在则断开连接
}
private void appServer_NewMessageReceived(WebSocketSession session, string message)
{
//收到来自客户端的消息,有可能是身份信息,也有可能是业务指令。如果是身份信息则修改索引器中用户基本信息,如果是业务指令,则操作相关业务
}
private void appServer_SessionClosed(WebSocketSession session, CloseReason closeRs)
{
//当客户端断开后事件,此处应删除已端开用户
}
好了,简单服务器端结构就完成了。
二、客户端
客户端应用我就直接上代码.
/// <summary>
/// 通信客户端类
/// </summary>
public class ClientCls
{
public WebSocket ws;
public event Action<string> OnReceived;
public event Action OnConnect;
public event Action OnClose;
public event Action OnOpen;
public ClientCls(string ip, string port)
{
ws = new WebSocket(string.Format(@"ws://{0}:{1}", ip, port));
ws.Opened += Ws_Opened;
ws.MessageReceived += Ws_MessageReceived;
ws.Closed += Ws_Closed;
}
public void Connect()
{
ws.Open();
}
private void Ws_Opened(object sender, EventArgs e)
{
OnOpen?.Invoke();
}
public void Send(string message)
{
//message =ZEncypt.DESEncrypt(message);
ws.Send(message);
}
private void Ws_Closed(object sender, EventArgs e)
{
OnClose?.Invoke();
}
private void Ws_MessageReceived(object sender, MessageReceivedEventArgs e)
{
OnReceived?.Invoke(e.Message);
}
}
好了,简单的收发就完成。