关于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
}
- 上一篇: 一个FileManager
- 下一篇: 关于与安卓通信