/// <summary> /// Send message data to specific group collection in asynchronous mode. /// </summary> /// <param name="groupNameCollection">The group collection to receive the message.</param> /// <param name="messageData">The message data to be sent to group collection.</param> /// <param name="offset">The offset of the message data.</param> /// <param name="count">The count of bytes to be sent.</param> /// <param name="callback">The callback that will be called after sending.</param> /// <param name="state">The user defined state.</param> /// <param name="loopBack">True if the message returns to the sender; otherwise false. The default is false.</param> /// <returns>An System.IAsyncResult that references the asynchronous send.</returns> public IAsyncResult SendGroupMessageAsync(IEnumerable <string> groupNameCollection, byte[] messageData, int offset, int count, AsyncCallback callback, object state, bool loopBack = false) { if (_clientStatus != ClientStatus.Connected) { throw new Exception(Constants.ExMessageClientNotConnected); } if (groupNameCollection == null) { throw new Exception("the group name collection can not be null"); } byte[] groupMessageData = GroupTransmitMessage.MakeGroupMessage(groupNameCollection, new ArraySegment <byte>(messageData, offset, count), loopBack); return(SendMessageAsync(groupMessageData, callback, state)); }
/// <summary> /// Send message data to specific group collection in synchronous mode. /// </summary> /// <param name="groupNameCollection">The group collection to receive the message.</param> /// <param name="messageData">The message data to be sent to group collection.</param> /// <param name="offset">The offset of the message data.</param> /// <param name="count">The count of bytes to be sent.</param> /// <param name="loopBack">True if the message returns to the sender; otherwise false. The default is false.</param> /// <returns>The number of bytes sent to the server.</returns> public int SendGroupMessage(IEnumerable <string> groupNameCollection, byte[] messageData, int offset, int count, bool loopBack = false) { if (_clientStatus != ClientStatus.Connected) { throw new Exception("the client is not connected"); } if (groupNameCollection == null) { throw new Exception("the group name collection can not be null"); } byte[] groupMessageData = GroupTransmitMessage.MakeGroupMessage(groupNameCollection, new ArraySegment <byte>(messageData, offset, count), loopBack); return(SendMessage(groupMessageData)); }
public static bool TryParse(ArraySegment <byte> messageRawData, out GroupTransmitMessage outMessage) { //| mark(4bytes) | group length(4bytes) | group names | real message data | try { if (messageRawData.Count < 10) { outMessage = null; return(false); } UInt32 transMessageMark = BitConverter.ToUInt32(messageRawData.Array, messageRawData.Offset); int groupDesLen = BitConverter.ToInt32(messageRawData.Array, messageRawData.Offset + 4); if (groupDesLen > TcpUtility.MaxGroupDesLength) { outMessage = null; return(false); } string groupNameDes = Encoding.UTF8.GetString(messageRawData.Array, messageRawData.Offset + 8, groupDesLen); if (string.IsNullOrWhiteSpace(groupNameDes)) { outMessage = null; return(false); } string[] groupArray = groupNameDes.Split('|'); IEnumerable <string> groupList = groupArray.Where(p => p.Trim() != ""); if (!groupList.Any()) { outMessage = null; return(false); } GroupTransmitMessage groupMessage = new GroupTransmitMessage() { GroupTransmitMessageMark = transMessageMark, GroupNameCollection = groupList, TransMessageData = new ArraySegment <byte>(messageRawData.Array, messageRawData.Offset + 8 + groupDesLen, messageRawData.Count - 8 - groupDesLen) }; outMessage = groupMessage; return(true); } catch { outMessage = null; return(false); } }
protected override void OnRawMessageReceived(TcpRawMessageReceivedEventArgs args) { if (args.Error == null) { ArraySegment <byte> rawSegment = args.Message.MessageRawData; if (rawSegment.Count >= 4) { UInt32 specialMark = BitConverter.ToUInt32(rawSegment.Array, rawSegment.Offset); if (specialMark == TcpUtility.JOIN_GROUP_MARK) { if (!EnableGroup) { return; } JoinGroupMessage joinGroupMsg = null; if (!JoinGroupMessage.TryParse(rawSegment, out joinGroupMsg)) { return; } if (_clients.TryGetValue(args.Message.ClientID, out ClientContext clientContext)) { clientContext.Groups = joinGroupMsg.GroupSet; AddClientToGroup(clientContext); } return; } else if (specialMark == TcpUtility.GROUP_TRANSMIT_MSG_MARK || specialMark == TcpUtility.GROUP_TRANSMIT_MSG_LOOP_BACK_MARK) { bool loopBack = specialMark == TcpUtility.GROUP_TRANSMIT_MSG_LOOP_BACK_MARK; if (!EnableGroup) { return; } GroupTransmitMessage transPacket = null; if (!GroupTransmitMessage.TryParse(rawSegment, out transPacket)) { return; } try { if (!ServerConfig.AllowCrossGroupMessage) { ClientContext sourceClient = GetClient(args.Message.ClientID); if (sourceClient == null || sourceClient.Groups == null || sourceClient.Groups.Count == 0) { return; } foreach (string groupName in transPacket.GroupNameCollection) { if (!sourceClient.Groups.Contains(groupName)) { return; } } } SendGroupMessageAsync(transPacket.GroupNameCollection, transPacket.TransMessageData.Array, transPacket.TransMessageData.Offset, transPacket.TransMessageData.Count , loopBack ? -1 : args.Message.ClientID); } catch (Exception ex) { _logger?.Warn("Transmit group message exception.", ex.Message); } return; } } if (ReceivedMessageFilter(args)) { return; } } MessageReceived?.Invoke(this, args); return; }