Realtime Communication using iOS Socket io Client and Sails JS

These days trend for real time communication and sync data is increasing rapidly. There are many technologies available to achieve real time communication but the Socket.io is being more popular at this moment. It’s very simple & easy to integrate for any platform and very fast compare to other options.

real time communication socket.io

Here I have chosen Sails JS server and iOS Socket.io client for real time communication. Let me write in detail about Why I have used Sails for real time communication between the client and the server?

“The easiest way to send a realtime message from a client to a Sails app with using the sails.io.js library. This library allows you to easily connect sockets to a running Sails app, and provides methods for making requests to Sails routes that are handled in the same manner as a “regular” HTTP request”.

Setting up Sails socket server for real time communication

I have created sample server code. We will follow one by one but if you want to jump directly then you will find the code here for Sails server. Let me write simple steps to run this project below.

Make sure you have Node.js and npm installed

$ git clone https://github.com/logisticinfotech/sailsjs-iosclient-socket-connections.git
$ cd sailsjs-iosclient-socket-connections

Install dependencies & start application

npm install
sails lift

Above command will open new window with this URL : http://localhost:1337. We will use this URL to connect with our iOS client. Certainly we will see that in next section.

Understanding Sails Resourceful PubSub

The Resourceful PubSub (Published/Subscribe) API provides a high-level way to subscribe sockets to Sails model classes and instances. It is entirely possible to create a rich real time experience (for example, a chat app) using just this API. Sails blueprints use Resourceful PubSub to automatically send out notifications about new model instances and changes to existing instances.

You just need to subscribe and unsubscribe with your model object.

User.subscribe(req, _.pluck(userobject, "id"));

User.unsubscribe(req, _.pluck(userobject, "id"));

Here you will see how event is being publish :-

User.publish(_.pluck(userobject, 'id'), {
    verb: 'published',
    data: data
}, req);

Below is important point about how to distinguish regular HTTP request and Socket request and as a result get Socket Id of request.

getSocketID: function(req, res) {  
    if (!req.isSocket) {    
       return res.badRequest();  
    }  
var socketId = sails.sockets.getId(req);  
sails.log('My socket ID is: ' + socketId);  
return res.json(socketId);}

Here let me write detail about useful configuration while we attempt to connect from client side. Where you can define your security setups and write important logics. There are many settings we can use but for now, I have written only two beforeConnect and afterDisconnect.

// Being called when connection gets established
beforeConnect: function(handshake, proceed) {
    console.log("Socket gets connected");
    return proceed(undefined, true);
},

// Being called when connection gets detached
afterDisconnect: function(session, socket, done) {
    sails.log("socket disconnected for socket id ", socket.id);
    return done();
},

Client side set up using iOS socket.io client

Here I have chosen iOS as a client, you can get the whole code here if you want to jump directly with it. Let me write in detail about how to connect iOS client with Sails server. Actually, the purpose of writing this article is to use resourceful pubsub methods of sails. We can call sails API like we are calling regular HTTP requests using socket.io.

Below you can see sample code for connection with server from client side.

var options:SocketIOClientConfiguration!
var socket: SocketIOClient!
var manager : SocketManager!

options = [] as SocketIOClientConfiguration
options.insert(.connectParams(["__sails_io_sdk_version":"1.0.2"]))
options.insert(.reconnectAttempts(1000))
options.insert(.reconnectWait(3))
options.insert(.log(false))
options.insert(.compress)
options.insert(.forceWebsockets(true))

manager = SocketManager(socketURL: URL(string: localhost:1337)!, config: options)
socket = manager.defaultSocket

socket.on(clientEvent:.connect) { (data, ack) in
	printLog("socket connected")
}

Here is example for GET and POST method being called from client side like regular HTTP requests.

let dictParameters = [ "url": String( http://localhost:1337 + "/onlineuser/userid")]
    self.socket.emitWithAck("get", with: [dictParameters]).timingOut(after: 10) {data in
    print("Socket data  for all users");
    print(data);
}
let dictParameters = [ "url": SocketDetails.SendPrivateMessage,
                       "data": ["userid" : userid,"touserid" : touserid,"msg":"chat message"]] as [String : Any]
        
    self.socket.emitWithAck("post", with: [dictParameters]).timingOut(after: 10) {data in
            
    if data[0] is NSDictionary
    {
        if (data[0] as! NSDictionary).object(forKey: "body") is NSDictionary
        {
            printLog("Send Private Message No Ack: \(data[0])")
            let responseBody = (data[0] as! NSDictionary).object(forKey: "body") as! NSDictionary
        }
    }
}

Here is an example of how to receive “on” method if you haven’t specified any specific on method then you can get it using onAny on client side.

socket.on("user") { data in
    print("user 1 ------------>", socket)
}
socket.onAny({ data in
    print("ANy event =====> \(data)" )
})

In this article, I have created simple one to one chat app using all the above concepts which I have explained. Certainly you can download code from here, let’s follow this steps to run the app on your Xcode.

Running App on your Xcode

pod install

After installing all the required pods, let’s start an iOS project and run on multiple Simulator or devices to communicate with each other. The first screen will ask you to enter the name for chat and it will create that name and that will be broadcasted to all users who are subscribed to receive user events. Same thing will happen while any user left or close app it will broadcast sockets to all subscribers.

You can select any user from the list to chat with them in real time. In this code, I have also handled events like user typing, message sent status etc. And that history will be there until user logs out from the app or close the app.

Actually, the purpose of the socket is not only limited to chat. You can also use this for any kind of real time requirements for that you just need to plan accordingly as per your needs. Hope this article will help you.

If you have any query, feel free to comment below.

Sails server

Don’t miss the next post!

Loading

Related Posts