/// <summary> /// Sends a message to the remote application. /// </summary> /// <param name="message">Message to be sent</param> protected override void SendMessageInternal(ICJiaMessage message) { //Send message var totalSent = 0; lock (_syncLock) { //Create a byte array from message according to current protocol var messageBytes = WireProtocol.GetBytes(message); //Send all bytes to the remote application while (totalSent < messageBytes.Length) { var sent = _clientSocket.Send(messageBytes, totalSent, messageBytes.Length - totalSent, SocketFlags.None); if (sent <= 0) { throw new CommunicationException("Message could not be sent via TCP socket. Only " + totalSent + " bytes of " + messageBytes.Length + " bytes are sent."); } totalSent += sent; } LastSentMessageTime = DateTime.Now; OnMessageSent(message); } }
/// <summary> /// This method is used to serialize a IScsMessage to a byte array. /// This method can be overrided by derived classes to change serialization strategy. /// It is a couple with DeserializeMessage method and must be overrided together. /// </summary> /// <param name="message">Message to be serialized</param> /// <returns> /// Serialized message bytes. /// Does not include length of the message. /// </returns> protected virtual byte[] SerializeMessage(ICJiaMessage message) { using (Net.Serialization.SerializationWriter sw = new Serialization.SerializationWriter()) { message.SerializeOwnedData(sw, null); return(sw.ToArray()); } }
/// <summary> /// Sends a message to the server. /// </summary> /// <param name="message">Message to be sent</param> /// <exception cref="CommunicationStateException">Throws a CommunicationStateException if client is not connected to the server.</exception> public void SendMessage(ICJiaMessage message) { if (CommunicationState != CommunicationStates.Connected) { throw new CommunicationStateException("Client is not connected to the server."); } _communicationChannel.SendMessage(message); }
/// <summary> /// Raises MessageSent event. /// </summary> /// <param name="message">Received message</param> protected virtual void OnMessageSent(ICJiaMessage message) { var handler = MessageSent; if (handler != null) { handler(this, new MessageEventArgs(message)); } }
/// <summary> /// Sends a message to the remote application. /// </summary> /// <param name="message">Message to be sent</param> /// <exception cref="ArgumentNullException">Throws ArgumentNullException if message is null</exception> public void SendMessage(ICJiaMessage message) { if (message == null) { throw new ArgumentNullException("message"); } SendMessageInternal(message); }
/// <summary> /// Raises MessageReceived event. /// </summary> /// <param name="message">Received message</param> private void OnMessageReceived(ICJiaMessage message) { var handler = MessageReceived; if (handler != null) { handler(this, new MessageEventArgs(message)); } }
/// <summary> /// Overrides /// </summary> /// <param name="message"></param> protected override void OnMessageReceived(ICJiaMessage message) { lock (_receivingMessageQueue) { if (_receivingMessageQueue.Count < IncomingMessageQueueCapacity) { _receivingMessageQueue.Enqueue(message); } _receiveWaiter.Set(); } }
/// <summary> /// Sends response to the remote application that invoked a service method. /// </summary> /// <param name="client">Client that sent invoke message</param> /// <param name="requestMessage">Request message</param> /// <param name="returnValue">Return value to send</param> /// <param name="exception">Exception to send</param> private static void SendInvokeResponse(IMessenger client, ICJiaMessage requestMessage, object returnValue, CJiaRemoteException exception) { try { client.SendMessage( new CJiaRemoteInvokeReturnMessage { RepliedMessageId = requestMessage.MessageId, ReturnValue = returnValue, RemoteException = exception }); } catch { } }
/// <summary> /// Sends a message and waits a response for that message. /// </summary> /// <remarks> /// Response message is matched with RepliedMessageId property, so if /// any other message (that is not reply for sent message) is received /// from remote application, it is not considered as a reply and is not /// returned as return value of this method. /// /// MessageReceived event is not raised for response messages. /// </remarks> /// <param name="message">message to send</param> /// <param name="timeoutMilliseconds">Timeout duration as milliseconds.</param> /// <returns>Response message</returns> /// <exception cref="TimeoutException">Throws TimeoutException if can not receive reply message in timeout value</exception> /// <exception cref="CommunicationException">Throws CommunicationException if communication fails before reply message.</exception> public ICJiaMessage SendMessageAndWaitForResponse(ICJiaMessage message, int timeoutMilliseconds) { //Create a waiting message record and add to list var waitingMessage = new WaitingMessage(); lock (_syncObj) { _waitingMessages[message.MessageId] = waitingMessage; } try { //Send message Messenger.SendMessage(message); //Wait for response waitingMessage.WaitEvent.Wait(timeoutMilliseconds); //Check for exceptions switch (waitingMessage.State) { case WaitingMessageStates.WaitingForResponse: throw new TimeoutException("操作超时.远程服务器无响应."); case WaitingMessageStates.Cancelled: throw new CommunicationException("收到响应前连接被中断."); } //return response message return(waitingMessage.ResponseMessage); } finally { //Remove message from waiting messages lock (_syncObj) { if (_waitingMessages.ContainsKey(message.MessageId)) { _waitingMessages.Remove(message.MessageId); } } } }
/// <summary> /// Serializes a message to a byte array to send to remote application. /// This method is synchronized. So, only one thread can call it concurrently. /// </summary> /// <param name="message">Message to be serialized</param> /// <exception cref="CommunicationException">Throws CommunicationException if message is bigger than maximum allowed message length.</exception> public byte[] GetBytes(ICJiaMessage message) { //Serialize the message to a byte array var serializedMessage = SerializeMessage(message); //Check for message length var messageLength = serializedMessage.Length; if (messageLength > MaxMessageLength) { throw new CommunicationException("Message is too big (" + messageLength + " bytes). Max allowed length is " + MaxMessageLength + " bytes."); } //Create a byte array including the length of the message (4 bytes) and serialized message content var bytes = new byte[messageLength + 4]; WriteInt32(bytes, 0, messageLength); Array.Copy(serializedMessage, 0, bytes, 4, messageLength); //Return serialized message by this protocol return(bytes); }
/// <summary> /// Creates a new MessageEventArgs object. /// </summary> /// <param name="message">Message object that is associated with this event</param> public MessageEventArgs(ICJiaMessage message) { Message = message; }
/// <summary> /// Sends a message to the client. /// </summary> /// <param name="message">Message to be sent</param> public void SendMessage(ICJiaMessage message) { _communicationChannel.SendMessage(message); }
/// <summary> /// 自定义序列化消息 /// </summary> /// <param name="message"></param> /// <returns></returns> protected override byte[] SerializeMessage(ICJiaMessage message) { return(Encoding.UTF8.GetBytes(((CJiaTextMessage)message).Text)); }
/// <summary> /// Sends a message to the remote application. /// This method is overrided by derived classes to really send to message. /// </summary> /// <param name="message">Message to be sent</param> protected abstract void SendMessageInternal(ICJiaMessage message);
/// <summary> /// Sends a message and waits a response for that message. /// </summary> /// <remarks> /// Response message is matched with RepliedMessageId property, so if /// any other message (that is not reply for sent message) is received /// from remote application, it is not considered as a reply and is not /// returned as return value of this method. /// /// MessageReceived event is not raised for response messages. /// </remarks> /// <param name="message">message to send</param> /// <returns>Response message</returns> public ICJiaMessage SendMessageAndWaitForResponse(ICJiaMessage message) { return(SendMessageAndWaitForResponse(message, Timeout)); }
/// <summary> /// Sends a message. /// </summary> /// <param name="message">Message to be sent</param> public void SendMessage(ICJiaMessage message) { Messenger.SendMessage(message); }