Hello folks.
As we explain in the last post about the cross-browser plugins, today we will continue by interacting between the browser and the plugin. For example like send actions, receive response, receive results, etc..

As you know the WebSocket is a computer communications protocol, providing full-duplex communication channels over a single TCP connection. You can send\receive any type of data, bytes like files, text, JSON objects.
The WebSocket protocol enables interaction between a browser and a web server with lower overheads, facilitating real-time data transfer from and to the server. This is made possible by providing a standardized way for the server to send content to the browser without being solicited by the client, and allowing for messages to be passed back and forth while keeping the connection open. In this way, a two-way (bi-directional) ongoing conversation can take place between a browser and the server.

How to proceed

We start be creating a WebSocket object, we choose the url. The URI scheme is ws (websocket) or wss (websocket security). You can define also a custom port.


	var mySocket = new WebSocket("ws://localhost/socketserver");

When creating an instance, it mean’s that you are connecting to the server. The returned object will have a property “readyState”, it’s value can be “CONNECTING” (while establishing a TCP connection) or “OPEN” if the connection was successful.
If you need to start sending some data directly on opening, I suggest you use the “onopen” event listener.


	mySocket.onopen = function (event) {
	  mySocket.send("Message on open the connection"); 
	};

Sending a message is quite easy using the method send.


	mySocket.send("Hello folks, it's a fancy message"); 

Sending a JSON object through the socket is also quite simple.


	var objectToSend = {
		date: new Date(),
		message: 'Hello folks',
		userId: 23,
		anyOtherProperties....
	};
	mySocket.send(JSON.stringify(objectToSend)); 

To receive the messages from the server, we use the event “onmessage”


	mySocket.onmessage = function (event) {
		var data = event.data;//contains the data received from the server.
		//parsing the data if you are using JSON.
		var obj = JSON.parse(data);
	};

But how do you know that the message received is for what type of purpose, like if you need to login or receiving a success result for or getting the list of all users, etc..
This is also a quite fancy 🙂


	mySocket.onmessage = function (event) {
		var data = event.data;//contains the data received from the server.
		//parsing the data if you are using JSON.
		var obj = JSON.parse(data);
		//you should add a data type.
		switch(obj.TYPE){
			case "LOGIN":
				//call loginResponse(obj);
			break;
			case "USERS":
				//call listUsers(obj);
			break;
			case "BROADCAST":
				//call broadcast(obj);
			break;
		}
	};

Once you’re done from the client, you need to close the connection.


	mySocket.close();

I will handle the implementation of server side in .Net, you can use your own development language like nodeJS, Java, etc..
In .net I am using the SuperSocket library. This library allows me to handle the websocket protocol from any type of application, windows forms, windows services, Asp.net, etc…
My class is called WebSocketHelper.


	public class WebSocketHelper
	{
	}

Adding some mandatory attributes for the class. The session is the opened session with the current user. But in our case the plugin is on the client machine, so there will be just one session opened at a time.


	protected WebSocketServer WebSocketServer { get; private set; } //the websocket server object
	protected WebSocketSession session; //websocket session
	private int port; //the port needed to create the server socket

	protected AutoResetEvent MessageReceiveEvent = new AutoResetEvent(false);
	protected AutoResetEvent DataReceiveEvent = new AutoResetEvent(false);
	protected AutoResetEvent OpenedEvent = new AutoResetEvent(false);
	protected AutoResetEvent CloseEvent = new AutoResetEvent(false);

	protected string CurrentMessage { get; private set; }
	protected byte[] CurrentData { get; private set; }

Adding constructor, and setup method to run the socket server.


	//constructor
	public WebSocketHelper(int port)
	{
		this.port = port;
	}

	//setup method to be called to run the server
	public virtual void Setup()
	{
		Setup(new WebSocketServer(), c =>
		{
			c.Port = port;
			c.Ip = "Any";
			c.MaxConnectionNumber = 100;
			c.MaxRequestLength = 100000;
			c.Name = "SuperWebSocket Server";
		});

		WebSocketServer.NewMessageReceived += new SessionHandler<WebSocketSession, string>(WebSocketServer_NewMessageReceived);
	}

	//internal setup to add events, and create the socket server
	protected void Setup(WebSocketServer websocketServer, Action<ServerConfig> configurator)
	{
		var rootConfig = new RootConfig { DisablePerformanceDataCollector = true };

		websocketServer.NewDataReceived += new SessionHandler<WebSocketSession, byte[]>(WebSocketServer_NewDataReceived);

		var config = new ServerConfig();
		configurator(config);

		var ret = websocketServer.Setup(rootConfig, config, null, null, new ConsoleLogFactory(), null, null);

		WebSocketServer = websocketServer;
	}

	public void StartServer()
	{
		WebSocketServer.Start();
	}

	public void StopServer()
	{
		WebSocketServer.Stop();
	}

We add now the event receivers for data and messages.


	protected void WebSocketServer_NewMessageReceived(WebSocketSession session, string e)
	{
		this.session = session;
		try
		{
			var data = JsonConvert.DeserializeObject<MyModel>(e);
			switch (data.TYPE)
			{
				case "LOGIN":
					session.Send(doLogin(data));
					break;
				case "USERS":
					session.Send(listUsers(data));
					break;
				case "BROADCAST":
					session.Send(broadCast(data));
					break;
			}
		}
		catch(Exception ex)
		{
			Logger.Error("WebSocketServer_NewMessageReceived", ex);
		}
	}

	protected void WebSocketServer_NewDataReceived(WebSocketSession session, byte[] e)
	{
		//you received here some sort of binary data
		//I am just returning it back.
		session.Send(e, 0, e.Length);
	}		

Finally we add the send method so we can send messages to client (session).


	public void SendMessage(object data)
	{
		try
		{
			if (session != null)
			{
				var text = JsonConvert.SerializeObject(data);
				session.Send(text);
			}
		}
		catch(Exception ex)
		{
			Logger.Error("SendMessage", ex);
		}
	}	

Guys, this was how do you interact with the browser. Your plugin is now alive and at your command ;).
In the next post we will share a full source code of a simple communication between browser and plugin.
Stay tuned 🙂