此文主要基于小程序+C#使用WebSocket制作一个聊天系统,基本实现小程序与服务端的聊天功能。用小程序自带的客服功能只能绑定微信且一对一沟通,接入市面上成熟的即时通讯预算又略显不足,干脆自己开发一个也能应对简单的业务场景。
实现流程1、服务端1.1、项目创建1.2、设计界面1.3、服务端功能实现 2、小程序2.1、小程序创建2.2、页面设计2.3、消息接收2.4、消息发送
实现流程
1、服务端
1.1、项目创建
打开Visual Studio,右侧选择创建新项目。 搜索框输入winform,选择windows窗体应用,填写对应的保存路径点击下一步,创建成功后如下图。1.2、设计界面
在工具箱拖拽出lable文本标签修改其text属性填充标题。 拖拽textbox控件到窗体上用于输入所监听的端口号及发送的文本信息等。 接下来依次拖入button控件及listview控件实现按钮及消息面板样式。1.3、服务端功能实现
实现websocket服务端启动功能。双击button按钮,会生成对应的按钮事件,在事件代码中先获取端口号文本框输入的值是否正确。
int port = 9000; if (textBox_port.Text == string.Empty) { MessageBox.Show("请填写端口", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } try { port = Convert.ToInt32(textBox_port.Text.Trim()); } catch { MessageBox.Show("请填写正确的端口", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information); return; }
在点击后,将按钮禁用,避免用户重复点击的同时开启服务端。
try{ var result = _server.Open(port, "DIS"); if (result) { this.toolStripLabel_event.Text = "启动成功"; this.toolStripLabel_event.ForeColor = Color.Green; this.toolStripLabel1.Text = "监听端口:" + port.ToString(); WSocketServer._Logger.Info("服务器启动成功"); } else { this.toolStripLabel_event.Text = "启动失败"; this.toolStripLabel_event.ForeColor = Color.Red; this.toolStripLabel1.Text = "监听端口:" + port.ToString(); button_StartListen.Enabled = true; button_StopListen.Enabled = false; button_Send.Enabled = false; WSocketServer._Logger.Error("服务器启动失败"); } } catch (Exception ex) { WSocketServer._Logger.Error("服务器启动失败:"+ ex.ToString()); }
实现开启服务端的方法,这里需要对websocket的各项信息进行配置。
this.WebSocket = new WebSocketServer();var serverConfig = new ServerConfig{ Name = serverName, MaxConnectionNumber = 10000, //最大允许的客户端连接数目,默认为100。 Mode = SocketMode.Tcp, Port = port, //服务器监听的端口。 ClearIdleSession = false, //true或者false, 是否清除空闲会话,默认为false。 ClearIdleSessionInterval = 120,//清除空闲会话的时间间隔,默认为120,单位为秒。 ListenBacklog = 10, ReceiveBufferSize = 64 * 1024, //用于接收数据的缓冲区大小,默认为2048。 SendBufferSize = 64 * 1024, //用户发送数据的缓冲区大小,默认为2048。 KeepAliveInterval = 1, //keep alive消息发送时间间隔。单位为秒。 KeepAliveTime = 60, //keep alive失败重试的时间间隔。单位为秒。 SyncSend = false};SocketServerFactory socketServerFactory = null;//开启wss 使用证书if (isUseCertificate){ serverConfig.Security = serverSecurity; serverConfig.Certificate = new SuperSocket.SocketBase.Config.CertificateConfig { StoreName = serverStoreName, StoreLocation = System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine, Thumbprint = serverThumbprint }; socketServerFactory = new SocketServerFactory();}
实现消息发送功能。 双击发送按钮,获取客户端网络节点号向其发送数据并将发送的文本填充至消息面板。
//客户端网络节点号string remoteEndPointStr = session.RemoteEndPoint.ToString();if (remoteEndPointStr == s){ try { ReceiveData sendData = new ReceiveData(); //发送数据 sendData.User = "guest"; sendData.Type = "msg"; sendData.Msg = textBox_msg.Text.Trim(); sendData.SendTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); _server.SendMessage(session, JsonConvert.SerializeObject(sendData)); this.BeginInvoke(addListView, "guest", JsonConvert.SerializeObject(sendData)); MessageBox.Show("发送成功", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } catch (Exception ex) { WSocketServer._Logger.Error(ex.ToString()); MessageBox.Show(ex.ToString(), "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information); return; }}
实现消息监听功能,接收来自客户端的数据并进行展示。 /// <summary> /// 接收到的数据 /// </summary> /// <param name="session">session</param> /// <param name="rData">value</param> private void Server_MessageReceived(SuperWebSocket.WebSocketSession session, string rData) { //IP地址 string ipAddress_Receive = session.RemoteEndPoint.ToString(); if (rData.Equals("")) { //空数据不返回服务器信息 return; } try { //接收到客户端链接发送的东西 ReceiveData receiveData = JsonConvert.DeserializeObject<ReceiveData>(rData); receiveData.SendTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); switch (receiveData.Type) { case "HeartBeat": //心跳 //发送客户端连接成功信息 //_server.SendMessage(session, "HeartBeat"); break; default: //返回用户发送数据 _server.SendMessage(session, JsonConvert.SerializeObject(receiveData)); break; } } catch { WSocketServer._Logger.Error("接收异常数据:" + rData); //错误数据不反回服务器信息 return; } if (MsgFalg) { //服务端显示客户端发送接受信息 this.BeginInvoke(addListView, ipAddress_Receive, rData); } }
2、小程序
2.1、小程序创建
访问微信公众平台,点击账号注册。 选择小程序,并在表单填写所需的各项信息进行注册。2.2、页面设计
页面上根据发送人判断消息在哪边展示,同时还需要提供一个文本框以及按钮实现发送功能。<view class="cu-chat" id="j_page"> <view class="cu-item {{item.User==''?'self':''}}" wx:for="{{chatData}}"> <view class="cu-avatar radius" style="background-image:url(../../image/cat.jpg)" wx:if="{{item.User=='guest'}}"></view> <view class="main"> <view class="content shadow {{item.User==''?'bg-green':''}}"> <text>{{item.Msg}}</text> </view> </view> <view class="cu-avatar radius" style="background-image:url(../../image/fm3.jpg)" wx:if="{{item.User==''}}"></view> <view class="date">{{item.SendTime}}</view> </view></view>
通过文本框的blur事件获取用户所输入的内容。 formMsg(e) { this.setData({ content: e.detail.value.trim() }) },
2.3、消息接收
在js的onload事件中创建websocket的连接,同时监听来自服务端的消息,端口号可以改成配置型。 let that = this; socket = wx.connectSocket({ url: 'ws://localhost:9000/', success: res => { //console.info('创建连接成功'); } }); // console.info(socket); //事件监听 socket.onOpen(function () { //console.info('连接打开成功'); }); socket.onClose(function () { //console.info('连接关闭成功'); }); socket.onError(function () { console.info('连接报错'); }); //服务器发送监听 socket.onMessage(function (e) { console.info(JSON.parse(e.data)); var info = JSON.parse(e.data); that.setData({ chatData: that.data.chatData.concat(info) }); // that.setData({chatData:list}); });
在监听的回调中,将服务端发送的文本进行打印可以看到效果如下图。 2.4、消息发送
发送按钮绑定自定义函数,获取文本框中用户输入的值,并通过websocket的内置函数将数据进行传输,这样服务端就能对数据进行接收展示。 wx.sendSocketMessage({ data: info, success: function (res) { }, fail: function (res) { } })
有兴趣的小伙伴可以在文章基础上进行拓展,可以增加例如群发、文件、图片发送等更加实用的功能。