Read message by sequence in socket - ios

I have build a socket to transfer message between client and server on IOS.
if(CFReadStreamSetClient(readStream, registeredEvents, readCallBack, &myContext))
{
CFReadStreamScheduleWithRunLoop(readStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
}
if (!CFReadStreamOpen(readStream)) {
CCLog("Error Open Read Stream");
/* error handling */
}
and readCallBack function
void readCallBack(CFReadStreamRef stream, CFStreamEventType eventType, void *clientCallBackInfo)
{
switch(eventType) {
case kCFStreamEventHasBytesAvailable:{
UInt8 bufr[10240];
int bytesRead = CFReadStreamRead(stream, bufr, sizeof(bufr));
if(bytesRead >0 ){
NSLog(#"Read: %d", bytesRead);
}
break;
}
case kCFStreamEventErrorOccurred:
NSLog(#"A Read Stream Error Has Occurred!");
case kCFStreamEventEndEncountered:
NSLog(#"A Read Stream Event End!");
default:
break;
}
}
But when client send multi message to server by multi time.
Server always read it as one message.
Example:
Client send message 1st: Message1
Client send message 2nd: Message2
But when server read message from client:
Result is: Message1Message2
How can i split it as 2 messages. (I don't know the size of each message)
Thanks.

You have to make up a protocol of your own. For example, clients can append \n to each message so that the server can split messages by \n. However if your messages can have \n character in them, you can modify your protocol to first send the length of the message, again split by \n:
Client sends: 8\nMessage1
Client sends: 14\nAnotherMessage
Server receives: 8\nMessage114\nAnotherMessage
So you read up to first \n and get the content length. Then you read that many characters.
Be careful with the difference between byte streams and text streams though. You can google about TCP text streams to learn more about them. Your best bet is to send number of bytes being sent, instead of number of characters.
And be aware that sometimes, you will not receive a message as a whole. For example the following is possible:
Client sends: 8\nMessage1
Client sends: 14\nAnotherMessage
Server receives: 8\nMessage11
Server receives: 4\nAnotherMessage

Related

Kafka standalone error: WARN Attempting to send response via channel for which there is no open connection, connection id 0 (kafka.network.Processor)

I install kafka on a standalone server and try to stream data to mongodb.
when start kafka service, bin/kafka-server-start.sh config/server.properties
I had a warning:
WARN Attempting to send response via channel for which there is no open connection, connection id 0 (kafka.network.Processor)
Even though, there is no problem for data entered at producer and displayed at consumer.
but I think this cause the data write to mongodb. I have no data write to mongodb after start data streaming.
anyone can help with this issue? Thank you so much.
//processor.sendResponse
protected[network] def sendResponse(response: RequestChannel.Response) {
trace(s"Socket server received response to send, registering for write and sending data: $response")
val channel = selector.channel(response.responseSend.destination)
// `channel` can be null if the selector closed the connection because it was idle for too long
if (channel == null) {
warn(s"Attempting to send response via channel for which there is no open connection, connection id $id")
response.request.updateRequestMetrics()
}
else {
selector.send(response.responseSend)
inflightResponses += (response.request.connectionId -> response)
}
so, channel was closed by the selector because it was idle too long

Problems subscribing to a room (socket) with Socket.IO-Client-Swift and Swift, Sails.js on the Server

On Swift, I use
socket.on("test") {data, ack in
print(data)
}
In order to subscribe to a room (socket) on my Sails.js API.
When I broadcast a message from the server, with
sails.sockets.broadcast('test', { text : 'ok' })
the socket.on handler is never called.
However, if I set "log" TRUE to config when connecting my socket.io client from swift, in Socket-IO logs the message arrives.
What's wrong?
Eventually, I found my mistake:
The whole process I did is right:
(The request to join the room is done by the server, with sails.sockets.join)
Wrong thing was using socket.on with the ROOM NAME parameter.
I will explain it better, for others having same problem:
From Swift you should subscribe by making a websocket request to an endpoint on the server that accepts websocket requests (GET, POST, PUT). For example, you can make a POST request, passing in the room name into the body.
socket.emitWithAck("post", [
"room": "testroom",
"url": "/api/v1.0/roomsubscribing"
]).timingOut(after: 0) {data in
print("Server responded with \(data)")
}
On server side, inside the room-subscribing endpoint, you should have the following code:
roomSubscribing: function(req, res) {
if (!req.isSocket) {
return res.badRequest();
}
sails.sockets.join(req, req.params('room'), function(err) {
if (err) {
return res.serverError(err);
}
});
}
When the server want to broadcast some data to subscribers of the "testroom" room, the following code must be used:
sails.sockets.broadcast('testroom', { message: 'testmessage' }
Now on the swift's side you must use:
socket.on("message") { data, ack in
print(data)
}
in order to get the message handler to work. I thought you should use room name, instead you should use the KEY of the KEY/VALUE entry you used in your server when you broadcasted the data (in this case, "message").
I only have a small amount of experience with sockets, but in case nobody else answers...
I think you are missing step one of the three step socket process:
A client sends a message to the server asking to subscribe to a particular room.
The client sets up a socket.on to handle particular events from that room.
The server broadcasts an event in a particular room. All subscribers/clients with a .on for that particular event will react.
I could be wrong, but it sounds from your description like you missed step one. Your client has to send a message with io.socket, something like here, then your server has to use the socket request to have them join the room, something like in the example here.
(the presence of log data without the socket.on firing would seem to confirm that the event was broadcast in the room, but that client was not subscribed)
Good luck!

Mirth HL7 ACK ERROR: Message control Ids do not match

I'm starting out with Mirth and HL7 and I'm trying to send a message to a remote server. My MSH looks as follows:
MSH|^~\&|EPIC|EPIC|IMG_SCHEDULE_APPT|REMOTE|20170328193318|PERSONNAME|ORM^O01|12345678|T|2.4||||||||||
The response looks as follows:
MSH|^~\&|IMG_SCHEDULE_APPT|REMOTE|EPIC|EPIC|20170328193318||ACK|12345678|T|2.4|
MSA|AA|||
and I get an error saying ERROR: Message control Ids do not match.
As far as I understand this error means that the Message Control Id which is returned in the ACK message is not the same.
From what I can see, the number 12345678 is the Message Control Id, and I see that number both in the message I send as well as the in the ACK which is returned. So what is wrong here? And who is at fault? Me or the remote party?
Does anybody know how I can solve or debug this?
If you don't want to validate the message control ID, you can open the Response Validation properties and uncheck "Validate Message Control Id":
If the remote system cannot change their logic and you still want to validate the control ID, you can do that in a response transformer:
if (responseStatus == ERROR) {
// msg here is the ACK, origMsg is the encoded data that was sent outbound
var origMsg = new XML(SerializerFactory.getSerializer('HL7V2').toXML(connectorMessage.getEncodedData()));
if (origMsg.MSH['MSH.10']['MSH.10.1'].toString() == msg.MSH['MSH.10']['MSH.10.1'].toString()) {
responseStatus = SENT;
}
}
MSA.2 (Message Control ID) is required and should be the same as the ControlId in the former message that the ACK message acknowleges..

can i send function key to unix server through telnet

I want to access unix server on my iPod and this is almost done and i am able to send and receive data from server but when i send a function key (F1, F2,...) to server, server sends me same value that i have sent.
For example : F1 as key code is \e[OP .
My code for this-
SignedByte functionKeyEscSeq[5];
int index=0;
functionKeyEscSeq[index++]='\e';
switch (keyCode) {
case 0://Done
[self unhideAllDefaultButtons];
break;
case 1://F1 //PF1 Key
functionKeyEscSeq[index++]='O';
functionKeyEscSeq[index++]='P';
break;
.....
}
[self sendByte:functionKeyEscSeq toIndex:index]; // Method to send this byte array with socket connection
My Question : Is it possible to send function Key to Server.
If it is possible then please send me some reference or format by which it is possible.
As far I know, you must set your telnet terminal type as TERMINAL_TYPE=vt200 in order to send function keys.

Mirth: How to send ACK message to sender host and port

I am receiving lab HL7 messages from a static host and a dynamic port. For each message received I need to send a ACK message back to this host and port.
I have a destination TCP Writer channel with the correct message in there. Though the port number has to be fixed.
How do I tell Mirth to send this message to the sending host and port?
Thanks in advance
Abhi
You should configure your channel to use the LLP Listener instead, which has the option to reply with a custom HL7 ACK message. The message will be send back on the same connection so you don't have to keep track of the address of the sending system.
In Mirth you send a customized ACK message.
In Scripts, select the Postprocessor (This script executes once after a message has been processed)
and write this code
var ackString = ""; //build a javascript string for your custom ack
var ackResponse = ResponseFactory.getSuccessReponse(ackString);
responseMap.put("Custom ACK", ackResponse);
Mirth will then parse the Postprocessor script, and discovers the reponseMap code. On the source tab, go to the Send ACK radio list, you can now select "Respond from" and "Custom ACK" from the options in the dropdownlist avaiable.

Resources