/// <summary> /// 客户端取消订阅 /// </summary> /// <param name="unSubScribeFrame"></param> /// <param name="stompBehavior"></param> public void UnSubScribe(StompFrame unSubScribeFrame, StompBehavior stompBehavior) { lock (stompSubscribeDictionaryLock) { if (unSubScribeFrame.Headers.ContainsKey(StompHeaders.Id) && string.IsNullOrEmpty(unSubScribeFrame.Headers[StompHeaders.Id])) { string destinationOfsubid = stompBehavior.topicPathSubidDictionary.FirstOrDefault(d => d.Value == unSubScribeFrame.Headers[StompHeaders.Id]).Key; if (stompSubscribeDictionary.ContainsKey(destinationOfsubid)) { if (stompSubscribeDictionary[destinationOfsubid].ContainsKey(stompBehavior.ID)) { stompSubscribeDictionary[destinationOfsubid].Remove(stompBehavior.ID); } } } } }
/// <summary> /// when stompBehavior closing,need remove subscribe /// </summary> /// <param name="stompBehavior"></param> public void StompBehaviorOnClose(StompBehavior stompBehavior) { lock (stompSubscribeDictionaryLock) { foreach (var destination in stompBehavior.topicPathSubidDictionary.Keys) { if (stompSubscribeDictionary.ContainsKey(destination)) { if (stompSubscribeDictionary[destination].ContainsKey(stompBehavior.ID)) { stompSubscribeDictionary[destination].Remove(stompBehavior.ID); if (stompSubscribeDictionary[destination].Count == 0) { stompSubscribeDictionary.Remove(destination); } } } } } }
/// <summary> /// 添加一个新的订阅地址 /// </summary> /// <param name="subScribeFrame">客户端的订阅数据包</param> /// <param name="stompBehavior">客户端连接对象</param> /// <returns>null:Success,not NULL:ERROR</returns> public StompFrame SubScribe(StompFrame subScribeFrame, StompBehavior stompBehavior) { //* If the server cannot successfully create the subscription, the server MUST send the client an ERROR frame and disconnect the client. lock (stompSubscribeDictionaryLock) { if (!subScribeFrame.Headers.ContainsKey(StompHeaders.Destination)) { return(new ErrorFrame("Headers missing:'destination'", "SUBSCRIBE 包必须携带'destination'头,而且值不能为空.\nSUBSCRIBE Frame's headers MUST Contain 'destination',and the value MUST NOT null/empty", subScribeFrame)); } else if (string.IsNullOrEmpty(subScribeFrame.Headers[StompHeaders.Destination])) { return(new ErrorFrame("Header['destination'] MUST NOT be null or empty", "SUBSCRIBE 包规定header['destination']的值不能为空.\nSUBSCRIBE Frame's header['destination']: MUST NOT be null/empty", subScribeFrame)); } else if (!subscribeSupportTopicList.Contains(subScribeFrame.Headers[StompHeaders.Destination])) { return(new ErrorFrame("Stomp Server not support this destination", "Stomp Server not support this destination : '" + subScribeFrame.Headers[StompHeaders.Destination] + "'\n", subScribeFrame)); } else if (!subScribeFrame.Headers.ContainsKey(StompHeaders.Id))//subid { return(new ErrorFrame("Headers missing: 'id'", "SUBSCRIBE 包必须携带'id'头,而且值不能为空.\nSUBSCRIBE Frame's headers MUST Contain 'id',and the value MUST uniquely" + "\nSince a single connection can have multiple open subscriptions with a server, an id header MUST be included in the frame to uniquely identify the subscription.", subScribeFrame)); } else if (string.IsNullOrEmpty(subScribeFrame.Headers[StompHeaders.Id])) { return(new ErrorFrame("Header['id'] MUST NOT be null or empty,and MUST uniquely.", "SUBSCRIBE 包必须携带'id'头,而且值必须唯一.\nSUBSCRIBE Frame's header['id'] MUST NOT null/empty,and MUST uniquely.", subScribeFrame)); } if (stompBehavior.topicPathSubidDictionary.Values.Contains(subScribeFrame.Headers[StompHeaders.Id]))// check id { if (stompBehavior.topicPathSubidDictionary.Keys.Contains(subScribeFrame.Headers[StompHeaders.Destination]) && stompBehavior.topicPathSubidDictionary[subScribeFrame.Headers[StompHeaders.Destination]] == subScribeFrame.Headers[StompHeaders.Id]) { return(null); } else { // subid 已经用在了别的地址上 string destinationOfsubid = stompBehavior.topicPathSubidDictionary.FirstOrDefault(d => d.Value == subScribeFrame.Headers[StompHeaders.Id]).Key; return(new ErrorFrame("SUBSCRIBE: ['id'] MUST uniquely", "this sub-id is alread been used with this destination:" + destinationOfsubid + ".\n sub-id MUST uniquely,please use another id", subScribeFrame)); //stompBehavior.topicPathSubidDictionary[subScribeFrame.Headers[StompHeaders.Destination]] = subScribeFrame.Headers[StompHeaders.Id];//update sub-id } } if (stompBehavior.topicPathSubidDictionary.ContainsKey(subScribeFrame.Headers[StompHeaders.Destination]))//check destination { // 已经订阅过,id都匹配 if (stompBehavior.topicPathSubidDictionary[subScribeFrame.Headers[StompHeaders.Destination]] == subScribeFrame.Headers[StompHeaders.Id]) { return(null); } else //换了一个sub-id { // destination已经匹配了一个sub-id //return new ErrorFrame("SUBSCRIBE: ['destination'] already linked a sub-id", "this destination is alread linked a sub-id:" + stompBehavior.topicPathSubidDictionary[subScribeFrame.Headers[StompHeaders.Destination]] + ".\n Stomp Server Don't want client Subscribe one destination by many times.", subScribeFrame); // update sub-id stompBehavior.topicPathSubidDictionary[subScribeFrame.Headers[StompHeaders.Destination]] = subScribeFrame.Headers[StompHeaders.Id]; } } // // ack ... Not support! // // // Stomp1.0 // The body of the SUBSCRIBE command is ignored. // if (!stompBehavior.topicPathSubidDictionary.ContainsKey(subScribeFrame.Headers[StompHeaders.Destination])) { stompBehavior.topicPathSubidDictionary.Add(subScribeFrame.Headers[StompHeaders.Destination], subScribeFrame.Headers[StompHeaders.Id]);//stompBehavior<destination:id> Add } //SubscribeFlowDirction subscribeFlowDirction = GetSubscribeFlowDirction(subScribeFrame.Headers[StompHeaders.Destination]); //if (subscribeFlowDirction == SubscribeFlowDirction.Application || subscribeFlowDirction == SubscribeFlowDirction.Unkonw)//Unkonw is Error ? //{ // return null; //} if (stompSubscribeDictionary.ContainsKey(subScribeFrame.Headers[StompHeaders.Destination])) { var idStompBehaviorKV = stompSubscribeDictionary[subScribeFrame.Headers[StompHeaders.Destination]]; if (!idStompBehaviorKV.ContainsKey(stompBehavior.ID)) { stompSubscribeDictionary[subScribeFrame.Headers[StompHeaders.Destination]].Add(stompBehavior.ID, stompBehavior); } } else { stompSubscribeDictionary.Add(subScribeFrame.Headers[StompHeaders.Destination], new Dictionary <string, StompBehavior>() { { stompBehavior.ID, stompBehavior } }); } } return(null); }