zoukankan      html  css  js  c++  java
  • Socket,长连接,消息推送,消息提醒,未读消息提醒,消息通知,未读消息通知

    今天公司要搞个类似QQ空间的未读消息通知,于是想到用WebSocket长连接,搜索一些资料后,调试好久,还以为不行,结果发现是IIS版本的原因,我本地用的Win7的系统,是IIS6的,本地测试一直不行,后来查资料发现用这个WebSocket要IIS8,我直接放服务器上,测试就OK了,废话不多说,直接上代码。我用的MVC+EF的框架。

    1、新建一个Controller,继承APIController

    [Description("消息")]
    public class MessageController : ApiController
    {

    //注入消息通知的业务逻辑
    public readonly NoticeService NoticeService = new NoticeService();


    [AcceptVerbs("post", "get")]
    [Description("长连接线程检测")]
    public HttpResponseMessage ProcessRequest()
    {
    if (HttpContext.Current.IsWebSocketRequest)
    {
    HttpContext.Current.AcceptWebSocketRequest(ProcessChat);
    return new HttpResponseMessage(HttpStatusCode.SwitchingProtocols);
    }
    else
    {
    return new HttpResponseMessage(HttpStatusCode.SwitchingProtocols);
    }

    }

    //发送信息回客户端
    private async Task ProcessChat(AspNetWebSocketContext context)
    {

    WebSocket socket = context.WebSocket;
    while (true)
    {
    if (socket.State == WebSocketState.Open)
    {
    ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[2048]);
    WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);

    //约定好客户端只传用户ID过来
    string userId = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);

    var operateUserId = Convert.ToInt32(userId);
    //默认没有
    buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes("false"));
    for (int i = 0; i < 100; i++)
    {

    //我这默认30秒查询一次数据库,判断是否有未读消息然后提示客户端,大家对这有什么好的建议吗?请交流一下好的idea,我想的是这循环100次,100*30秒也有50分钟了,基本还是够用了,正常情况也没有谁50分钟一直在线操作的吧。很LOW的想法,请大家给我good idea,我要改进,我觉得这样处理很low,但是短时间又没好的想法
    Thread.Sleep(30000);

    //查询数据库是否有这个userid的未读消息,Type=2是未读消息
    var messages = await
    NoticeService.MessageInfos()
    .CountAsync(p => p.OwerId == userId && p.Type == 2);
    buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(messages.ToString()));

    //返回未读消息的个数为messages==0没有未读消息,messages>0有未读消息
    await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
    }
    await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);

    }
    else
    {
    break;
    }
    }
    }


    }

    以上就是服务器端的代码,下面开始客户端的代码

    2、客户端怎么发起长连接喃?请往下看

    <html>

    <head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    @*<script src="jquery-2.0.3.min.js"></script>*@
    <script src="~/Content/Js/jquery/jquery.min.js" type="text/javascript"></script>
    <script>
    var ws;
    $().ready(function ()
    {
    $('#conn').click(function ()
    {

    //替换下面的IP地址和端口号
    ws = new WebSocket('ws://' + '你的服务器代码所在的IP地址' + ':' + '端口号' + '/API/Message/ProcessRequest');

    $('#tips').text('正在连接');
    ws.onopen = function ()
    {
    $('#tips').text('已经连接');
    }
    ws.onmessage = function (evt)
    {
    $('#tips').text(evt.data);
    }
    ws.onerror = function (evt)
    {
    $('#tips').text(JSON.stringify(evt));
    }
    ws.onclose = function ()
    {
    $('#tips').text('已经关闭');
    }
    });

    $('#close').click(function ()
    {
    ws.close();
    });

    $('#send').click(function ()
    {
    if (ws.readyState == WebSocket.OPEN) {
    ws.send($('#content').val());
    }
    else {
    $('#tips').text('连接已经关闭');
    }
    });

    });
    </script>
    </head>
    <body>
    <form id="form1" runat="server">
    <div>

    <input id="conn" type="button" value="连接" />
    <input id="close" type="button" value="关闭" />
    <span id="tips"></span>
    <input id="content" type="text" />
    <input id="send" type="button" value="发送" />
    </div>
    </form>
    </body>

    </html>

    3、开始测试

    点击连接,输入框输入ID,测试OK,完事

    我这默认30秒查询一次数据库,判断是否有未读消息然后提示客户端,大家对这有什么好的建议吗?请交流一下好的idea

  • 相关阅读:
    关于Linux联网的问题
    MapD的数据导出与扩容(利用现有的表)
    系统重启后,MapD报错Thrift的连接被拒绝
    关于Linux系统只读(Ubuntu16.4.1)
    javaBean的依赖注入中构造注入和依赖注入的区别
    Struts2开发中遇到的坑。。。
    通过配置文件设置定时任务,以及时间的选择
    微信小程序开发的movable开发的坑
    spring基础概念
    Hibernate的三种查询方式
  • 原文地址:https://www.cnblogs.com/wjslw/p/6073276.html
Copyright © 2011-2022 走看看