I am using the new PushStreamContent entity in MVC4 to stream notifications from my web server back to multiple listening iOS clients (they are using NSURLConnection). The messages being sent are JSON. When I send messages that are less than 1024 bytes, the message sends as expected. Sending messages larger than this size however causes the client to receive the message in multiple chunks, each being 1024 bytes.
I am wondering what is the best way for my iOS clients to consume these multiple messages coming back? Is there a way to have NSURLConnection aggregate the results for me, or do I need to implement something that gets a result, checks if it's valid json, if not wait for the next result and append the previous, and continue until it is valid? What is a better way of doing this?
I found that you are able to adjust the size of the buffer that writes data to the stream that PushStreamContent uses. However, chunking the data is the correct thing for it to do and keeping this small has several advantages. I ended up writing my own method to aggregate the data flowing in on the client side. See the following question for more details:
How to handle chunking while streaming JSON data to NSURLConnection
Related
I have a .Net Remoting service that will return a class to the client application. That class has a string property where the string can range from 1kb to 400kb worth of data.
I tried passing 256kb worth of string from server to client and the client was able to get it in less than 5 seconds which is still ok since this call will only be used for trouble-shooting purposes by an administrator. However I read
here that when sending huge data: "the socket will be blocked from receiving all other messages until it receives the remaining .... packets". If my data ever reached an MB size I do not want to block the client from receiving other messages.
How can I achieve my goal of not blocking the client? Do I compress the string using GZipStream like in here? Or are there other better ways?
Good article from Tess Fernandez : https://blogs.msdn.microsoft.com/tess/2008/09/02/outofmemoryexceptions-while-remoting-very-large-datasets/
I'm currently developing service in which client communicate with server by sending xml files with messages. In order to improve reliability of messaging (client will be using low quality limited bandswitch mobile internet) I chunks these message in smaller portions of 64 or 128 Kb size, and send them with transfer="streamed" in BasicHttp binding.
Now, I have a problem:
server should report to client, if he succesfully received a chunk or not, so after f.e 5 chunks failed to transfer, the transfer process will be cancelled and postponed to be tried later, and to keep track of which chunks are received and which are not.
I'm thinking about using callback mechanism to communicate client, so server will invoke callback method ChunkReceived in it's [OperationContract], when it saves chunk to the file on the server-side, but, correct me if I'm wrong, but callback only works with WS Dual http binding, and isn't supported in basichttp binding. But streamed transfer isn't supported in WS Dual binding.
So is it ok for me to switch to WS Dual binding and use transfer="buffered" (considering chunk size is relatively small) - won't that hurt reliability of the transfer? Or maybe I can somehow communicate with client in basic http binding, maybe by returning some kind of response message, i.e.
[OperationContract]
ServerResponse SendChunk (Chunk chunk);
where ServerResponse will hold some enum or bool flag to tell the client if the SendChunk operation is ok. But then I will have to keep some kind of array on both client and server side to keep track of all the chunks status. I'm just not sure what's the best pattern to use there. Any advice would be highly appreciated.
We had similar problem in our application - low bandwidth and many disconnects/timeouts. We have smaller messages, so we didn't split them, but the solution should work to for chunks too. We've created Repeater on client. This proven to be reliable solution - it works well on clients with slow, poor connections(like GPRS - being on the move disconnected often). Also client won't get timeout errors if server slows down due to high load. Here is modified version, with chunks
Client:
1. Client sends Chunk#1, with pretty short timeout time
2. Is there OK response:
2A. Yes - proceed to next chunk
3. Was that last chunk?
3A. Yes - process reponse
3B. No - send next chunk
2B. No - repeat current chunk
Server:
Accept request
Is Chunk repeated
2A. Yes:
Is final chunk:
3A. Yes - check if response is ready, else wait(this propably will make client repeat)
3B. No - send Ok reponse
2B. No:
Save request somewhere (list, dictionary etc.)
Is this last chunk:
5A. Yes - Process message, save Reponse, and send it to client
5B. No - Send Ok Message
I have created a stream based on a stateless protocol, think 2 web servers sending very limited requests to each other.
As such neither will know if I suddenly stop one as no connection will close, there will simply be no requests. There could legitimately be a gap in requests so I don't want to treat the lack of them as a lost connection.
What I want to do is send a heartbeat to say "I'm alive", I obviously don't want the heartbeat data when I read form the stream though, so my question.
How do I create a new stream class that wraps another stream and sends heartbeat data without exposing that to calling code?
Assuming 2 similar implementations on both sides: send each block of data with a header so you can safely send Zero-data heartbeat blocks. I.e. translate Write on outer stream into several writes on inner stream like "{Data, 100 bytes, [bytes]}, {Data, 13 bytes, [bytes]}", heartbeat would look like "{Ping, 0 bytes, []}". On receiving end immediately respond with similar empty Ping.
Im writing a server application for my iPhone app. The section of the server im working on is the relay server. This essentially relays messages between iPhones, through a server, using TCP sockets. The server reads the length of the header from the stream, then reads that number of bytes from the stream. It deserializes the header, and checks to see if the message is to be relayed on to another iPhone (rather than being processed on the server).
If it has to be relayed, it begins reading bytes from the sender's socket, 1024 bytes at a time. After each 1024 bytes are received, it adds those bytes (as a "packet" of bytes) to the outgoing message queue, which is processed in order.
This is all fine, however, but what happens if the sender gets interrupted, so it hasn't sent all its bytes (say, out of the 3,000 bytes it had to send, the sending iPhone goes into a tunnel after 2,500 bytes)?
This means that all the other devices are waiting on the remaining 500 bytes, which dont get relayed to them. Then if the sender (or anyone else for that matter) sends data to these sockets, they think the start of the new message is the end of the last one, corrupting the data.
Obviously from the description above, im using message framing, but I think im missing something. From what I can see, message framing only seems to allow the receiver to know the exact amount of bytes to read from the socket, before assembling them into an object. Wont things start to get hairy once a byte or two goes astray at some point, throwing everything out of sync? Is there a standard way of getting back in sync again?
Wont things start to get hairy once a byte or two goes astray at some point, throwing everything out of sync? Is there a standard way of getting back in sync again?
TCP/IP itself ensures that no bytes go "missing" over a single socket connection.
Things are a bit more complex in your situation, where (if I understand correctly) you're using a server as a sort of multiplexer.
In this case, here's some options off the top of my head:
Have the server buffer the entire message from point A before sending it to point B.
Close the B-side sockets if an abnormal close is detected from the A side.
Change the receiving side of the protocol so that a B-side client can detect and recover from a partial A-stream without killing and re-establishing the socket. e.g., if the server gave a unique id to each incoming A-stream, then the B client would be able to detect if a different stream starts. Or have an additional length prefix, so the B client knows both the entire length to expect and the length for that individual message.
Which option you choose depends on what kind of data you're transferring and how easy the different parts are to change.
Regardless of the solution, be sure to include detection of half-open connections.
I'm writing a server application for an iPhone application im designing. iPhone app is written in C# (MonoTouch) and the server is written in C# too (.NET 4.0)
I'm using asynchronous sockets for the network layer. The server allows two or more iPhones ("devices") to connect to each other and be able to send data bi-directionally.
Depending on the incoming message, the server either processes the message itself , or relays the data through to the other device(s) in the same group as the sending device. It can make this decision by decoding the header of the packet first, and deciding what type of packet it is.
This is done by framing the stream in a way that the first 8 bytes are two integers, the length of the header and the length of the payload (which can be much larger than the header).
The server reads (asynchronously) from the socket the first 8 bytes so it has the lengths of the two sections. It then reads again, up to the total length of the header section.
It then deserializes the header, and based on the information within, can see if the remaining data (payload) should be forwarded onto another device, or is something that the server itself needs to work with.
If it needs to be forwarded onto another device, then the next step is to read data coming into the socket in chunks of say, 1024 bytes, and write these directly using an async send via another socket that is connected to the recipient device.
This reduces the memory requirements of the server, as i'm not loading in the entire packet into a buffer, then re-sending it down the wire to the recipient.
However, because of the nature of async sockets, I am not guaranteed to receive the entire payload in one read, so have to keep reading until I receive all the bytes. In the case of relaying onto its final destination, this means that i'm calling BeginSend() for each chunk of bytes I receive from the sender, and forwarding that chunk onto the recipient, one chunk at a time.
The issue with this is that because I am using async sockets, this leaves the possibility of another thread doing a similar operation with the same recipient (and therefore same final destination socket), and so it is likely that the chunks coming from both threads will get mixed up and corrupt all the data going to that recipient.
For example: If the first thread sends a chunk, and is waiting for the next chunk from the sender (so it can relay it onwards), the second thread could send one of its chunks of data, and corrupt the first thread's (and the second thread's for that matter) data.
As I write this, i'm just wondering is it as simple as just locking the socket object?! Would this be the correct option, or could this cause other issues (e.g.: issues with receiving data through the locked socket that's being sent BACK from the remote device?)
Thanks in advance!
I was facing a similar scenario a while back, I don't have the complete solution anymore, but here's pretty much what I did :
I didn't use sync sockets, decided to explore the async sockets in C# - fun ride
I don't allow multiple threads to share a single resource unless I really have to
My "packets" were containing information about size, index and total packet count for a message
My packet's 1st byte was unique to signify that it's a start of a message, I used 0xAA
My packets's last 2 bytes were a result of a CRC-CCITT checksum (ushort)
The objects that did the receiving bit contained a buffer with all received bytes. From that buffer I was extracting "complete" messages once the size was ok, and the checksum matched
The only "locking" I needed to do was in the temp buffer so I could safely analyze it's contents between write/read operations
Hope that helps a bit
Not sure where the problem is. Since you mentioned servers, I assume TCP, yes?
A phone needs to communicate some of your PDU to another phone. It connects as a client to the server on the other phone. A socket-pair is established. It sends the data off to the server socket. The socket-pair is unique - no other streams that might be happening between the two phones should interrupt this, (will slow it up, of course).
I don't see how async/sync sockets, assuming implemented correctly, should affect this, either should work OK.
Is there something I cannot see here?
BTW, Maciek's plan to bolster up the protocol by adding an 'AA' start byte is an excellent idea - protocols depending on sending just a length as the first element always seem to screw up eventually and result in a node trying to dequeue more bytes that there are atoms in the universe.
Rgds,
Martin
OK, now I understand the problem, (I completely misunderstood the topology of the OP network - I thought each phone was running a TCP server as well as client/s, but there is just one server on PC/whatever a-la-chatrooms). I don't see why you could not lock the socket class with a mutex, so serializing the messages. You could queue the messages to the socket, but this has the memory implications that you are trying to avoid.
You could dedicate a connection to supplying only instructions to the phone, eg 'open another socket connection to me and return this GUID - a message will then be streamed on the socket'. This uses up a socket-pair just for control and halves the capacity of your server :(
Are you stuck with the protocol you have described, or can you break your messages up into chunks with some ID in each chunk? You could then multiplex the messages onto one socket pair.
Another alternative, that again would require chunking the messages, is introduce a 'control message', (maybee a chunk with 55 at start instead of AA), that contains a message ID, (GUID?), that the phone uses to establish a second socket connection to the server, passes up the ID and is then sent the second message on the new socket connection.
Another, (getting bored yet?), way of persuading the phone to recognise that a new message might be waiting would be to close the server socket that the phone is receiving a message over. The phone could then connect up again, tell the server that it only got xxxx bytes of message ID yyyy. The server could then reply with an instruction to open another socket for new message zzzz and then resume sending message yyyy. This might require some buffering on the server to ensure no data gets lost during the 'break'. You might want to implement this kind of 'restart streaming after break' functionality anyway since phones tend to go under bridges/tunnels just as the last KB of a 360MB video file is being streamed :( I know that TCP should take care of dropped packets, but if the phone wireless layer decides to close the socket for whatever reason...
None of these solutions is particularly satisfying. Interested to see whay other ideas crop up..
Rgds,
Martin
Thanks for the help everyone, i've realised the simpliest approach is to use synchronous send commands on the client, or at least a send command that must complete before the next item is sent. Im handling this with my own send queue on the client, rather than various parts of the app just calling send() when they need to send something.