Integrating Socket.io with Unity 5 WebGL

Published May 21, 2016 by Damian Oslebo, posted by Damian Oslebo
Do you see issues with this article? Let us know.
Advertisement

Introduction

WebSockets are a great choice to implement networking in your Unity WebGL games. WebSockets provide two-way persistent connection to a server. Unfortunately, WebSockets in Unity WebGL is limited at this time. There is a sample source library package in the Unity Store from the Unity Team, however, websocket functionality is not fully implemented. This article proposes the use of Javascript Socket.io to implement persistent p2p communication through a web server.

A particular useful aspect of Socket.io is that the server code can be written in Javascript. This allows for the code to be analogous on both the server and client sides for better clarity and maintenance.

Explaining the Concept

There are three major parts to this approach in order to implement Socket.io with your WebGL game:

  1. Setting up a network communication script within Unity
  2. Creating the javascript client code
  3. Creating the javascript server code

Data is then passed back and forth to the Unity Game by converting the data to/from JSON objects and strings.

Implementation

Project Setup

In order to try this method out for yourself Node.js must be installed on your server. Once installed, open up a command line terminal and change directory to your Unity Project WebGL Build. Then create a JSON file titled package.json in that directory with the following contents:

{ "dependencies": { "express": "4.13.4", "socket.io": "1.4.5" } }

The actual latest version can be obtained from the command "npm info express version". After the file is created:

  1. Run "npm install" to download node modules for express and socket.io into your build directory.
  2. Create a folder "public" in the root of your unity build directory
  3. Create a blank "client.js" script inside the "public" folder

Unity Specific Code

The following is an example template that you would use to interact with the external client-side javascript that would in turn interact with the server script.

The JSONUtility class is leveraged in the example, since only string data can be passed via Application.externalCall and its corresponding receiver method on the client javascript side.

Data can be passed for execution in the browser using:

Application.ExternalCall (string functionName, string dataParameter);

Ideally, we should set some data classes first before coding the nnetwork manager to aid in conversion to/from Json Objects using JSONUtility:

// Sample Data Classes that could be stringified by JSONUtility public class User { public string uid; public string displayname; public User(string u,string d) { uid = u; displayname = d; } } public class MatchJoinResponse { public bool result; }

Next create a C# script named "NetworkManager" and attach to a GameObject in your scene:

using UnityEngine; public class NetworkManager : MonoBehaviour { public void ConnectToServer(User user) { Application.ExternalCall ("Logon", JsonUtility.ToJson (user)); } public void OnMatchJoined(string jsonresponse) { MatchJoinResponse mjr = JsonUtility.FromJson (jsonresponse); if(mjr.result) { Debug.Log("Logon successful"); } else { Debug.Log("Logon failed"); } } public void BroadcastQuit() { Application.ExternalCall ("QuitMatch"); } }

When you rebuild your Unity project. Make sure you now add the following lines to the "index.html" file:

Client Javascript

The client javascript accepts calls from the Unity Game running in the previous section and connects with the server in the next section. Calls are forwarded back to the Unity Game with the following call:

SendMessage(string GameObjectName, string MethodName, string data);

The example uses a timeout to prevent locking up your game in the event the server is down. In the client.js file:

var connection; var logonTimeout; var logonCallback = function (res) { clearTimeout(logonTimeout); // Send Message back to Unity GameObject with name 'XXX' that has NetworkManager script attached SendMessage('XXX','OnMatchJoined',JSON.stringify(response)); }; function Logon(str) { var data = JSON.parse(str); connection = io.connect(); // Setup receiver client side function callback connection.on('JoinMatchResult', logonCallback); // Attempt to contact server with user data connection.emit('JoinMatchQueue', data); // Disconnect after 30 seconds if no response from server logonTimeout = setTimeout(function(){ connection.disconnect(); connection = null; var response ={result:false}; // Send Message back to Unity GameObject with name 'XXX' that has NetworkManager script attached SendMessage('XXX','OnMatchJoined',JSON.stringify(response)); },30000); } function QuitMatch() { if(connection) { connection.disconnect(); connection = null; } }

Server Javascript

The example server is setup using express for routing and file delivery simplicity. The server and client functions are analogous in this example.

// Variable Initialization var express = require('express'), app = express(), server = require('http').createServer(app), port = process.env.PORT || 3000, io = require('socket.io')(server); // Store Client list var clients = {}; // Allow express to serve static files in folder structure set by Unity Build app.use("/TemplateData",express.static(__dirname + "/TemplateData")); app.use("/Release",express.static(__dirname + "/Release")); app.use(express.static('public')); // Start server server.listen(port); // Redirect response to serve index.html app.get('/',function(req, res) { res.sendfile(__dirname + '/index.html'); }); // Implement socket functionality io.on('connection', function(socket){ socket.on('JoinMatchQueue', function(user){ socket.user = user; clients[user.uid] = socket; var response ={result:true}; socket.emit('JoinMatchResult', response); console.log(user.uid + " connected"); }); socket.on('disconnect', function() { delete clients[socket.user.uid]; console.log(socket.user.uid + " disconnected"); }); });

Once saved, the server can then be started on your home computer with Node.js with the command line "node server.js".

Other Notes

There is most likely a performance consideration in your game. Data is converted to and from JSON objects and strings from the browser and back in the game; each conversion is necessary overhead in this approach. I would be interested in hearing if anyone implementing this method has any information regarding any performance hit experienced.

Also, if implementing Socket.io on an Azure server, make sure the following line is also added in the website's web.config file:

This disables the IIS WebSockets module, which includes its own implementation of WebSockets and conflicts with Node.js specific WebSocket modules such as Socket.IO.

Conclusion

This article presented a way to network with Socket.io and WebGL builds of Unity.

Obviously a better way to execute Socket.io and Unity interoperability would be a plugin solely hosted in the Unity environment. The solution presented in this article is a extensible alternative until such time that Unity implements websocket functionality natively into its game engine. Finally, there is added benefit in that the javascript client and server codes will be very similar.

Article Update Log

10 Apr 2016: Initial release

Cancel Save
0 Likes 3 Comments

Comments

PanicBot

Hi, thanks for the tips, it`s help to understand the basic for using socket.io with unity.

Howether, what do you mean after saying : -"When you rebuild your Unity project. Make sure you now add the following lines to the "index.html" file:" *and then nothing*

What should have we add to the index.html file ?

And there is the same empty black box in the conclusion, I`m confused :(

November 30, 2017 04:03 PM
heroicbanana151

ngotha na unna kettana da punda

March 02, 2020 06:35 AM
chefstudios

I'd use something like webtick.gg for this. Best networking solution available IMO. Uses Netcode and WebRTC instead of websockets, so it's a lot faster and more stable.

December 01, 2022 05:56 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!

Interested in setting up multiplayer networking over WebGL Unity? This article provides a framework for use in your Unity web builds.

Advertisement

Other Tutorials by Damian Oslebo

Advertisement