{"id":7428,"date":"2019-09-27T21:30:21","date_gmt":"2019-09-27T21:30:21","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=7428"},"modified":"2019-09-27T21:30:49","modified_gmt":"2019-09-27T21:30:49","slug":"websockets-with-javascript","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/websockets-with-javascript\/","title":{"rendered":"Websockets with JavaScript"},"content":{"rendered":"<p>Let&#8217;s create a JavaScript websocket server. <\/p>\n<p>To start with carry out the following steps&#8230;<\/p>\n<ul>\n<li>Create a folder, mine&#8217;s wsserver and cd to it<\/li>\n<li>Run yarn init -y<\/li>\n<li>Run tsc &#8211;init<\/li>\n<li>Run yarn add ws @types\/ws<\/li>\n<li>Add a file (mine&#8217;s server.ts) for our server code<\/li>\n<li>Add another file this time for a sample client (mine&#8217;s client.ts)<\/li>\n<ul>\n<p>Now we will add the scripts, so add the following to package.json<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n&quot;scripts&quot;: {\r\n  &quot;server&quot;: &quot;node server.js&quot;,\r\n  &quot;client&quot;: &quot;node client.js&quot;\r\n  &quot;build&quot;: &quot;tsc&quot;\r\n}\r\n<\/pre>\n<p>Let&#8217;s add some code, in the server.js put the following<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nimport WebSocket from &quot;ws&quot;;\r\n\r\nconst wss = new WebSocket.Server({ port: 4000 });\r\n\r\nwss.on(&quot;connection&quot;, ws =&gt; {\r\n  ws.on('message', message =&gt; {\r\n    console.log('received: %s', message);\r\n  });\r\n\r\n  ws.on(&quot;close&quot;, () =&gt; {\r\n    console.log(&quot;Close connection&quot;);\r\n  });\r\n\r\n  ws.send(&quot;Server says Hi&quot;);\r\n});\r\n<\/pre>\n<p>In the above code we create a new websocket server on port 4000 then we handle any connection&#8217;s (once a connection is made the server sends back the message &#8220;Server says Hi&#8221;. The ws.on &#8220;message&#8221; will output any messages sent from the client. It should be fairly obvious that the &#8220;close&#8221; is called when a connection is closed.<\/p>\n<p>Let&#8217;s now put the following in the client.ts<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nimport WebSocket from &quot;ws&quot;;\r\n\r\nconst ws = new WebSocket(&quot;ws:\/\/localhost:4000&quot;);\r\n\r\nws.onopen = () =&gt; {\r\n  ws.send(&quot;Client says Hi&quot;);\r\n};\r\n\r\nws.onerror = error =&gt; {\r\n  console.log(error);\r\n}\r\n\r\nws.onmessage = msg =&gt; {    \r\n  console.log(`Client onmessage: ${msg.data}`);\r\n}\r\n\r\nws.onclose = () =&gt; {\r\n  console.log(&quot;Close&quot;);\r\n};\r\n<\/pre>\n<p>In the above we open the connection to the web socket server, when the connection is open (onopen) we send a message &#8220;Client says Hi&#8221; to the server, obviously any errors are sent to the onerror function and any message from the server are routed to the onmessage function, finally onclose is called if the server closes the connection.<\/p>\n<p>Now run the script command <em>yarn build<\/em> and then in one terminal run <em>yarn server<\/em> and in another terminal run <em>yarn client<\/em>.<\/p>\n<p>We can also send specific commands to the server, for example in the client add the following to the onopen function<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nws.send(&quot;getData&quot;);\r\n<\/pre>\n<p>Within the server add the following<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nws.on(&quot;getData&quot;, msg =&gt; {\r\n  console.log(&quot;getData called&quot;)\r\n});\r\n<\/pre>\n<p>So now when the server receives a <em>getData<\/em> messages it&#8217;s routed to this server function.<\/p>\n<p>If we have multiple client&#8217;s connecting to a server, we can send messages to each client using code, like the following<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nwss.clients.forEach(client =&gt; {\r\n  if (client.readyState === WebSocket.OPEN) {\r\n    client.send(&quot;Broadcasting a  message);\r\n  }\r\n});\r\n<\/pre>\n<p>We can also extend the server &#8220;connection&#8221; function like this<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nwss.on(&quot;connection&quot;, (ws, request) =&gt; {\r\n  console.log(request);\r\n}\r\n<\/pre>\n<p>The <em>request<\/em> parameter allows us to check the <em>request.url<\/em> if we want to change take different actions depending upon the query part of the websocket URL.<\/p>\n<p>It&#8217;s often useful to implement ping\/pong capabilities which would allow us to check if the client still exists, here&#8217;s rather simplistic example of this type of code.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nwss.on(&quot;connection&quot;, (ws, request) =&gt; {\r\n  ws.isAlive = true;\r\n\r\n  ws.on(&quot;pong&quot;, () =&gt; {\r\n    console.log(&quot;Pong called&quot;);\r\n    ws.isAlive = true;\r\n  });\r\n\r\n  setInterval(function ping() {\r\n    wss.clients.forEach(function each(ws: any) {\r\n      if (ws.isAlive === false)  {\r\n        console.log(&quot;Terminated client&quot;)\r\n        return ws.terminate();\r\n      }\r\n        \r\n      ws.isAlive = false;\r\n      console.log(&quot;Ping client&quot;)\r\n      ws.ping();\r\n    });\r\n  }, 10000);\r\n});\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Let&#8217;s create a JavaScript websocket server. To start with carry out the following steps&#8230; Create a folder, mine&#8217;s wsserver and cd to it Run yarn init -y Run tsc &#8211;init Run yarn add ws @types\/ws Add a file (mine&#8217;s server.ts) for our server code Add another file this time for a sample client (mine&#8217;s client.ts) [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[45,46,267],"tags":[],"class_list":["post-7428","post","type-post","status-publish","format-standard","hentry","category-javascript","category-typescript","category-websocket"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/7428","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=7428"}],"version-history":[{"count":5,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/7428\/revisions"}],"predecessor-version":[{"id":7461,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/7428\/revisions\/7461"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=7428"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=7428"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=7428"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}