As i am bit new to Rx and learning my way through it. I checked out lots of examples out there but none fits my need.
Scenario : I have one socket server socket (created using simple socket object and not TCPListener object). I have multiple clients (client socket and not TCPClient) connected to this server socket. I am trying to use Rx (Reactive extension) to get the messages sent by client socket by using “FromAsyncPattern” operator for BeginReceive and EndReceive asynchrounous operation.
I have almost started getting the messages in the buffer. But the issue is that the buffer return either the same message received from previous operation or will have mix content from current and previous receive operation.
Here is the code used :
private void ReceiveMessageFromClient(Socket socket)
{
try
{
if (socket != null)
{
byte[] buffer = new byte[400];
var functionReceiveSocketData = Observable.FromAsyncPattern
<byte[], int, int, SocketFlags, int>(socket.BeginReceive, socket.EndReceive);
Observable.Defer(() =>
functionReceiveSocketData(buffer, 0, 400, SocketFlags.None)
).Repeat().Subscribe(onNext: x => OnMessageReceived(buffer));
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
OnMessageReceived method is just an delegate to raise the message received event and send the buffer to other class to process further.
Problem : The same buffer is used evertime i get message how can i get the message received clean from previous received buffer.
— What should be done if i have message received partially and the next message is actually part of this same message.
Please help me out with the above issue with some code snippets which would be greatful. Reason of posting this question is cause the implementation i have gone through till now are using TCPListener and here the constraint is to use socket object 🙁
Thanks in advance.
The issue you’re hitting is that you’re sharing the same instance of your buffer between repeated calls to your observable. You need to ensure that you have a new buffer instance each time. It also appears that you should truncate the buffer based on the return integer. Here’s what I suggest that needs to go in your
ifstatement:EDIT: In response to the comment re joining message parts. Also fixed the solution above – should be
0and notnin theCopyTofunction in thecopylambda.I’m not an expert on using sockets, but, because the socket is (and correct me if I’m wrong) just a stream of bytes, you would need to be able to determine when each message in the stream is complete.
Here’s one possible way to do it:
The only thing you’d need to do is figure out how to implement the
isCompleteMessagefunction.