Socket.io
Socket.io is a library that allows a server to do server pull and server push. Server Push means the server can send something to the client without the client requesting it.
Socket.io relies on WebSockets for Web Applications.
It's useful to
- π Push notifications to the client
- β¨ Push events to the client (instead of querying the API periodically for updates, just listen for new events)
- πΉ Making chat applications
Or more generally, making real-time applications. The server can push data to the client without being requested (server push).
Basic usage
Socket.io is quite easy to use.
-
Listen to an event:
on("eventName", callback)
-
Stop listening to an event:
off("eventName")
-
Stop listening to every event:
off()
-
Emit an event:
emit("eventName", JSON_DATA)
// ex: node client listening to "event"
client.on("event", (data) => {
// send a reply
client.emit("event-ack", data)
// stop listening to event
client.off("event")
})
Express Node.js server
This code targets node.js applications running Express.js. You may use Socket.io with other libraries such as Angular...
$ npm i socket.io
In a project generated with express-generator, append to bin/www
/**
* Create Socket.io listener
*/
app.io = require('socket.io')(server)
// you may remove this later
app.io.on('connection', () => {
console.log('A new client connected to WebSockets')
})
CORS
See Handling CORS.
Ex: allowing any host to make requests.
- app.io = require('socket.io')(server)
+ app.io = require('socket.io')(server, {
+ cors: {
+ origin: "*"
+ }
+}
And in app.js
, you must add a middleware
app.use((req,res,next) => {
req.io = () => (app.io);
next();
});
Then, in any request, you can fetch io
for req
.
router.post('/message', (req, res) => {
req.io().emit('new-message', res.body)
});
There are many other alternatives, but I like this one because we are using a function, so we don't copy inside every request the io
object, and we can use it everywhere from the req
object.
Node.js client
You could create a socket.io client to test your code
$ npm i socket.io-client
const io = require("socket.io-client");
const client = io("http://localhost:3000");
client.on('connect', () => {
console.log("Connected");
});
HTML client
You need to add the following script (version 4.5.3). See cdnjs.
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.5.3/socket.io.js" integrity="sha512-iWPnCISAd/J+ZacwV2mbNLCaPGRrRo5OS81lKTVPtRg1wGTC20Cfmp5Us5RcbLv42QLdbAWl0MI57yox5VecQg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
const client = io("http://localhost:3000");
client.on('connect', () => {
console.log("Connected");
});
Android client (Kotlin)
See Also
- Native Socket.IO and Android
- Socket.io Connection on Android Kotlin to Node.js Server
- socket.io-android-chat
You must add the library in build.gradle
dependencies {
...
+ implementation ('io.socket:socket.io-client:2.0.0') {
+ exclude group: 'org.json', module: 'json'
+ }
...
}
Then, let's create a handler for our Socket.io connection.
package xxx
import io.socket.client.IO
import io.socket.client.Socket
import java.net.URISyntaxException
object SocketIOHandler {
private lateinit var _socket: Socket
val socket: Socket
get() = _socket
fun init() {
try {
_socket = IO.socket("http://10.0.2.2:3000")
_socket.connect()
} catch (_: URISyntaxException) {}
}
fun dispose() {
_socket.disconnect()
}
}
If you don't have one, you need to add a class Application. Inside, you will need to initialize and close socket.io client.
<application
+ android:name=".MainApplication"
package xxx
import android.app.Application
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
import xxx.SocketIOHandler
class MainApplication : Application(), DefaultLifecycleObserver {
override fun onCreate() {
super<Application>.onCreate()
ProcessLifecycleOwner.get().lifecycle.addObserver(this)
SocketIOHandler.init()
}
override fun onDestroy(owner: LifecycleOwner) {
super.onDestroy(owner)
SocketIOHandler.dispose()
}
}
Then, you're now ready. For instance, in your MainActivity.
SocketIOHandler.socket.on("event") {
// fetch argument (use JSONArray for [])
val json = it[0] as JSONObject
// fetch values { key: value }
val value = json.getString("key")
val value = json.getJSONObject("key")
// ...
}
Additional notes
- Execute code when connected
SocketIOHandler.socket.on(Socket.EVENT_CONNECT) {
/* ... */
}