My socket server initialize X amount of clients on a pool, on a new connection I get one from the pool and start listening on a new task. When a message is received, that client get the socket message and run a new Task that manage the received data while it go back to keep receiving.
I think I am collision safe between clients, but if a client receive the same type of message fast enough the second one could use the same method the first message is running asynchronously.
Should I externalize managing the action to a new class and initialize a pool of "ActionManagers" so each message have his own and only care when they update a shared resource? Any better idea?
Related
I'm using SingalR in an application that sends alot messages in a short period of time.
let's say i have client A and client B.
Client A just sends messages and client B just listening to messages.
Client A sends the following messages in the following order: A->B->C->D
What i'm seeing is that Client B sometimes receives the messages in a different order, for example: B->A->C->D
It is important for maintain the same order i sent the messages.
I've looked online and i found people saying i should use async-await on the function on the hub that handles those messages.
public async Task hubMethod(msgObject msg)
{
await Clients.All.message(msg);
}
I'm not sure how that helps since each time i make a call from client A , singalR should create a new instance of the hub.
The only thing it does is wait for the singalR that it finished doing all it can do on the server in order to send the message to the other client and notifies it to client A.
So my question is this - is there a singalR or asp.net mechanism that make sure i receive the messages in the correct order on the other client or do i need to write my own mechanism (server or client) that reorders the messages if they are out of order - and if so, is there a library that already does it?
You need to write your own mechanism. SignalR in client B has no way to know in which order the clients messages were sent by client A because there is many things that could delay a specific message arrival, like network delay, the only thing SignalR can guarantee is the order in which the messages arrived.
If you really need to know the original order of the messages you could put a count inside the message and let client B sort them out. However i suggest you try another approach, because guaranteeing the order of delivery is not a easy task.
I am in the process of QuickFix service initiator implementation in c# which needs to do the following.
Listen to incoming QuoteRequest messages and save them to a local database/queue.
Our users will have the ability to hit the Bids on these quote requests. These selections will be saved in a local queue.
Service will need to read the queue and send Quote messages back to the sender.
Listen to QuoteResponse / BusinessReject and QuoteStatus Messages from the sender and store on our end.
I'm planning to have two threads in my service.
Thread 1: This will be used to listen to incoming QuoteRequest, Quote response, Businessreject and quotestatus messages.
Outgoing ExecutionReport will be sent from OnMessage event handler while cracking QuoteResponse message.
Those messages will get stored in our system and published on our sites/queue etc.
Thread 2: This will listen to another local queue and sends out Quote(bids) messages to the acceptor. Quotes will be sent out using Session.SendToTarget.
Is there a way to configure two instances of initiators to be used in each thread ? Or do I create one initiator and add two sessions.
Would it work if both initiators are using same socket server and port ? Also if a message is not cracked by one thread would it be available for the other thread ?
I couldnt find any example of a multithreaded approach to handle both incoming and outgoing messages.
Appreciate any inputs/recommendation on a correct approach to implementation.
This is only one connection, and only one session, so there should only be one Initiator.
You can set up different worker threads, but your various OnMessage() callbacks should be a common entry point. They can dispatch their received messages to your thread (you could have them push received messages into a queue or something for your threads to consume). Your threads can do what they need to do and then call sendToTarget as appropriate.
Above all else, try not to put any expensive logic in the QF callbacks; put it in the threads. Other than that, you can do what you want.
I am trying to write a c# server/client that will simultaneously send byte arrays over TCP across each other. I'm trying to wrap my head around how to accomplish this. All of the example I have seen wait for a message, then send a response. I need communication to happen simultaneously.
Would I need to create 2 separate TCP socket connections for ingoing & outgoing on both the server & client? Can I pass data simultaneously with 1 connection in a "full duplex" fashion? Any help is appreciated.
I would advise you to look at the asynchronous sockets. The reason is, that they don't block threads while receiving or sending data.
Socket.BeginReceive(buffer, offset, size, endReceiveMethod);
The endreceive method will be called when there are bytes received. (on a other thread)
This is the same for sending.
Socket.BeginSend(buffer, offset, size, endSendMethod);
I remember in the early days I was worried about reading and writing on the same thread, creating difficult constructions with read-timeouts etc and each client it's own thread.
This isn't needed with Asynchronous sockets. It doesn't use a single thread per client. It uses I/O Completion Ports http://msdn.microsoft.com/en-us/library/windows/desktop/aa365198(v=vs.85).aspx instead of blocking threads.
You should look into using select() method to listen on server and client file descriptor (or fd). http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.select.aspx
Basically, if you have a TCP server, let us say, fd0 and if the client sends a connect, then the server fd would create a new fd for the new connection, let us call it fd1. Now, you would want to do three things with these: (a) listen for newer incoming connections on fd0, (b) wait for reciving data on fd1, and (c) send data on fd1. Sending data is usually non-blocking, so you dont have to worry about that. But, for (a) and (b), you can use a select.. If there is data to be read on fd1, then you would get a read event. Likewise, if there is a new connection on fd0, then also you would get a read event and you can call accept.
I have been working with the following code published on msdn:
http://msdn.microsoft.com/en-us/library/fx6588te.aspx
I understand that the server application is not blocked whilst the application is waiting for new clients.
However can this application (or even sockets) for that matter handle multiple concurrent requests?
What would happen if client A and B connected at the same time?
If client A connects and the handling of its request takes 5 seconds, if client B connects a second later must it wait for client A to finish before its processing can start?
Or will client A and client B's requests be handled concurrently?
I have done some testing with this by putting Thread.Sleep(n) commands in between the receive/send data in the socket listener code. I can then send multiple requests to the socket and they appear to be handled. However the socket always handles them on the same thread id - which makes me believe that it isnt actually happening concurrently.
Especially given the description by microsoft that this app simply doesnt block whilst awaiting for new connections - does that mean it can handle concurrent connections?
[Update 2014]: It seems that the example has been modified since this answer was posted, as noted in this thread. The MSDN example now handles multiple incoming connections properly. Anyway, the general approach described here is correct and perhaps it can provide additional clarification.
When doing socket communication, you basically have a single listener socket for all incoming connections, and multiple handler sockets for each connected client.
Listening to incoming connections
When you start listening to a port, you create a socket with a callback method for incoming connections (this is referencing the example you mentioned). That's the one-and-only listener socket for that port number:
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
This line tells the listener to invoke the AcceptCallback method whenever a new client is connected (new connection callback). That method is the one which should do its work quickly, since it blocks other incoming connections.
Creating dedicated handler sockets
That is also why AcceptCallback must immediately create a dedicated "handler" socket with its own background data callback method (ReadCallback):
// inside AcceptCallback, we switch to the handler socket for communication
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state); // fired on a background thread
From that moment on, ReadCallback method is invoked whenever some data is received by your newly connected client.
Also, before returning, AcceptCallback needs to call listener.BeginAccept again, to continue listening to new incoming connections:
// this is the same server socket we opened previously, which will now
// continue waiting for other client connections: it doesn't care about
// the actual data transmission between individual clients
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
This part is omitted from the MSDN example, meaning it can only receive a single connection.
Receiving data
As soon as you get a packet of data from your client, ReadCallback method will be invoked. So, inside this data callback method, you need to read and process the received data, and then invoke the same BeginReceive method again (again, with ReadCallback as its data callback method).
[Edit]
The problem with MSDN example is that it allows connection of only a single client (listener.BeginAccept is called only once). To allow mulitple concurrent connections, you need to create a receive socket using handler.BeginReceive, and then call listener.BeginAccept to start listening to new clients.
Every socket will have a listen queue associated with it. This will have the pending/partially accepted incoming connections. The max number number of pending connections can be defined programmatically in listen() API, which is nothing but 'listener.Listen(100)' in this example. Having had this as 100 here, the socket 'listener' can have 150 (=2*100/2) pending connections in the listen queue.
I'm using ActiveMQ in a .Net program and I'm flooded with message-events.
In short when I get a queue-event 'onMessage(IMessage receivedMsg)' I put the message into an internal queue out of which X threads do their thing.
At first I had: 'AcknowledgementMode.AutoAcknowledge' when creating the session so I'm guessing that all the messages in the queue got sucked down and put into the memory queue (which is risky since with a crash, everything is lost).
So then I used: 'AcknowledgementMode.ClientAcknowledge' when creating the session, and when a worker was ready with the message it calls the 'commit()' method on the message. However, still all the messages get sucked down from the queue.
How can I configure it that ONLY an X amount of messages are being processed or are in an internal queue, and that not everything is being 'downloaded' right away?
Are you on .NET 4.0? You could use a BlockingCollection . Set it to the maximum amount it may contain. As soon as a thread tries to put in an excess element, the Add operation will block until the collection falls below the threshold again.
Maybe that would do it for throttling?
There is also an API for throttling in the Rx framework, but I do not know how it is implemented. If you implement your Queue source as Observable, this API would become available for you, but I don't know if this hits your needs.
You can set the client prefetch to control how many messages the client will be sent. When the Session is in Auto Ack, the client will only ack a message once its been delivered to your app via the onMessage callback or through a synchronous receive. By default the client will prefetch 1000 messages from the broker, if the client goes down these messages would be redelivered to another client it this was a Queue, otherwise for a topic they are just discarded as a topic is a broadcast based channel. If you set the prefetch to one then you client would only be sent one message from the sever, then each time your onMessage callback completes a new message would be dispatched as the client would ack that message, that is if the session is in Auto Ack mode.
Refer to the NMS configuration page for all the options:
http://activemq.apache.org/nms/configuring.html
Regards
Tim.
FuseSource.com