木骰

关于Http版的服务器推送?

一般用Socket连接的才会有服务器推送,http是没有的。因为socket连接服务器才能主动给客户端推消息。但是采用http连接有时候也会有需要服务器推送通知的需求。http想要实现一个类似的只能是由客户端主动请求服务器,询问是否有广播消息。

那么就定义一个推送的消息协议,客户端发送一个询问请求,服务器返回一个推送消息的列表,这个列表里包含了多条推送消息,以协议id做标识。下面代码用的protobuf做通信,响应里包含具体消息内容的byte数组,和对应的消息协议id,以协议id来区分反序列化的类型。然后再提供一个注册接口,把收到的消息推送给各功能模块。
两种询问的方式

1.心跳
http通信的客户端可能会有做一个心跳机制,那么就可以把定时询问这件事这个丢到心跳里。在心跳的响应消息里加一个标识,用来判定是否有推送消息,有则拉取一遍推送消息。或者也可以直接把推送消息放在心跳的响应里。

2.每个响应的消息头head
如果没有做心跳,那么想必也不会做定时询问了,因为询问本身其实就是心跳。那么可以把 服务器通知客户端有新消息这件事放在每一个请求响应的消息头中。在http的消息头里加一个标识,判定是否有新消息,有则重拉一下。这么做的话就是推送的消息可能会有一个很长时间的延迟,必须得在下一次请求之后才能知道这之前有没有推送消息。



using System.Collections;
using System.Collections.Generic;
using System;
public class MsgBoxMgr  {

    static Dictionary> msgNotify=new Dictionary< Type, Action >();

    #region 请求响应

    public static void GetBoxMsg()
    {
        GetPushBDCMsgReq req = new GetPushBDCMsgReq();
        NetHelper.Request( UriConsts.GET_USER_BDC_MSG, req, GetBoxMsgResp);
    }

    static void GetBoxMsgResp(GetPushBDCMsgResp resp)
    {
        for(int i=0,Imax=resp.bdcMsg.Count;inotify)
    {
        if(msgNotify.ContainsKey(type))
        {
            if (Array .IndexOf(msgNotify[type].GetInvocationList(), notify) < 0)
                msgNotify[type] += notify;
        } else
        {
            msgNotify.Add(type, notify);
        }
    }

    public static void RemoveNotify(Type type, Actionnotify)
    {
        if (!msgNotify.ContainsKey(type)||msgNotify[type]==null||
            Array.IndexOf(msgNotify[type].GetInvocationList(),notify)<0) return;
        msgNotify[type] -= notify;
        if (msgNotify[type] == null )
            msgNotify.Remove(type);
    }

    static void Dispatch(Type type,object msg)
    {
        if(msgNotify.ContainsKey(type)&&msgNotify[type]!=null)
        {
            msgNotify[type](msg);
        }
    }

    #region 消息映射
    static Dictionary msgMapping = new Dictionary ()
    {
        { Consts.BDC_MSG_TYPE_CHARGE_RESULT,typeof (OrderResultBdc) },
        { Consts.BDC_MSG_TYPE_PROP_EXPIRE,typeof (UserPropExpiredBDC) },
    };
    #endregion
}



— 于 共写了933个字
— 文内使用到的标签:

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*