使用微软原生websocket client访问公司的server

websocket 介绍

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。

HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
在这里插入图片描述

废话不多说下面上代码


client定义

首先定义一个client:

  private ClientWebSocket client = new ClientWebSocket();//实例化客户端对象

定义几个委托用来更新日志,状态,返回结果

  public Action<string> ActionUpdateString;//更新运行日志

        public Action<string> ActionUpdateStatus;//更新client状态

        public Action<RemoteJsonRecie> ActionUpdateResult;//上传收到的结果

client连接

        public void StartConnect(string ServerAddress)
        {            
            //如果已经连上了服务端,想要再次进行连接,需要进行判断,关闭当前连接后才能进行
            if (client.State == WebSocketState.Open)
            {
                if(ActionUpdateString != null)ActionUpdateString("当前client对象连接状态为open,若要重新连接,请先关闭当前连接");
                return;
            }
            try
            {
                client = new ClientWebSocket();//这一句不要进行状态判断,因为除了Open和Closed,还有Abort等好几种状态。干脆每次连接重新初始化。
                client.ConnectAsync(new Uri(ServerAddress), CancellationToken.None).Wait();
                if(ActionUpdateString!=null)ActionUpdateString("开启了连接" + DateTime.Now.ToString() + "\n");
            }
            catch (Exception ex)
            {
                if (ActionUpdateString != null) ActionUpdateString(ex.ToString() + DateTime.Now.ToString() + "\n");
                if (ActionUpdateString != null) ActionUpdateString("连接出现问题,请检查网络是否通畅,地址是否正确,服务端是否开启");
                return;
            }
            finally
            {
                if (ActionUpdateStatus != null) ActionUpdateStatus( client.State.ToString());
            }
            //开启receive线程
            StartReceiving(client);
        }

client 发送函数

//此处的RemoteJsonSend 是自己更具需要定义的一个序列化的类
 public void SendMsg(RemoteJsonSend rmj)
        {
            string sendjsondata = JsonConvert.SerializeObject(rmj);

            var array = new ArraySegment<byte>(Encoding.UTF8.GetBytes(sendjsondata));
            //此处需要捕捉异常,连接是否通畅?
            try
            {
                if (client.State == WebSocketState.Open)//连通状态才允许发送
                {
                    client.SendAsync(array, WebSocketMessageType.Text, true, CancellationToken.None);
                }
                else
                {
                    if (ActionUpdateString != null) ActionUpdateString("连接状态异常,请尝试重新连接");
                }
            }
            catch (Exception ex)
            {
                if (ActionUpdateString != null) ActionUpdateString(ex.ToString() + DateTime.Now.ToString() + "\n");
                return;
            }
            finally
            {
                if (ActionUpdateStatus != null) ActionUpdateStatus(client.State.ToString());
            }
        }

client异步接收函数

  /// <summary>
        /// 异步接收服务端数据,获取json数据后反序列化,然后显示到文本框控件中
        /// </summary>
        /// <param name="client"></param>
        public  async void StartReceiving(ClientWebSocket client)
        {
            if (client.State != WebSocketState.Open)//正常来说进入到此方法的状态都为Open
            {
                if (ActionUpdateStatus != null) ActionUpdateStatus(client.State.ToString());
                if (ActionUpdateString != null) ActionUpdateString("StartReceiving方法:连接状态异常,请尝试重新连接");
                return;
            }
            try//有可能中途连接断开
            {
                while (true)
                {
                    var array = new byte[2048];
                    if (!((client.State == WebSocketState.Open) || (client.State == WebSocketState.CloseSent)))
                    {
                        //接收消息的有效状态是Open和CloseSent,如果不是这两种状态,则退出。
                        //主动退出也会影响异步线程的接收,因此先进行判断
                        if (ActionUpdateStatus != null) ActionUpdateStatus ("Closed");
                        if (ActionUpdateString != null) ActionUpdateString("StartReceiving方法:连接状态异常,退出循环接收,请检查" + DateTime.Now.ToString() + "\n");
                        return;
                    }
                    var result = await client.ReceiveAsync(new ArraySegment<byte>(array), CancellationToken.None);
                    if (result.MessageType == WebSocketMessageType.Text)
                    {
                        //获取字节数组并转为字符串,此字符串应为json类型,需要反序列化
                        string jsonmsg = Encoding.UTF8.GetString(array, 0, result.Count);

                        try//将反序列化内容放入try中,避免无法匹配、内容为空等可能报错的地方
                        {
                            //将转换后的字符串内容进行json反序列化。
                            RemoteJsonRecie re = JsonConvert.DeserializeObject<RemoteJsonRecie>(jsonmsg);
                            if (re != null)
                            {
                                if (ActionUpdateResult != null)
                                    ActionUpdateResult(re);
                            }
                        }
                        catch (Exception ex)
                        {
                            //如果json反序列化出了问题
                            if (ActionUpdateString != null) ActionUpdateString(ex.ToString() + DateTime.Now.ToString() + "\n");//将错误类型显示出来
                            if (ActionUpdateString != null) ActionUpdateString(jsonmsg + "\n");//将收到的原始字符串显示出来
                        }
                    }
                }
            }
            catch (Exception ex)//看看什么类型的错误
            {
                if (ActionUpdateStatus != null) ActionUpdateStatus( client.State.ToString());
                //MessageBox.Show(ex.ToString());//暂且注释,弹出消息框影响观感
                if (ex.GetType().ToString() == "System.Net.WebSockets.WebSocketException" && client.State != WebSocketState.Open)
                {
                    //客户端关闭时会抛出此错误
                    if (ActionUpdateString != null) ActionUpdateString("连接被关闭,请检查网络或服务器" + DateTime.Now.ToString() + "\n");
                }
                else
                {
                    if (ActionUpdateString != null) ActionUpdateString(ex.ToString() + DateTime.Now.ToString() + "\n");
                }
            }
            //finally
            //{
            //    if (client != null)
            //    {
            //        client.Dispose();
            //    }
            //}
        }

client 关闭

 public void CloseConnection()
        {
            if (client.State == WebSocketState.Open)
            {
                try
                {
                    client.CloseAsync(WebSocketCloseStatus.Empty, string.Empty, CancellationToken.None);
                    client.Dispose();
                    if (ActionUpdateString != null) ActionUpdateString("主动关闭了连接" + DateTime.Now.ToString() + "\n");
                    if (ActionUpdateStatus != null) ActionUpdateStatus("Closed");

                }
                catch (Exception ex)
                {
                    if (ActionUpdateString != null) ActionUpdateString(ex.ToString() + DateTime.Now.ToString() + "\n");
                }
                finally
                {
                     if (ActionUpdateStatus != null) ActionUpdateStatus(client.State.ToString());
                }
            }
        }

完整版的代码可点击此处下载WEBSOCKET CLIENT

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值