{"id":1819,"date":"2014-12-27T19:19:11","date_gmt":"2014-12-27T19:19:11","guid":{"rendered":"http:\/\/41j.com\/blog\/?p=1819"},"modified":"2014-12-26T23:29:52","modified_gmt":"2014-12-26T23:29:52","slug":"gorilla-websockets-golang-simple-websockets-example","status":"publish","type":"post","link":"https:\/\/41j.com\/blog\/2014\/12\/gorilla-websockets-golang-simple-websockets-example\/","title":{"rendered":"Gorilla Websockets, golang simple websockets example"},"content":{"rendered":"<p>I <a href=\"http:\/\/41j.com\/blog\/2014\/12\/simple-websocket-example-golang\/\">previously posted a quick example of using the standard library websockets API in golang<\/a>. Unfortunately there are a number of issues that make difficult to use in practice. Notably, it lacks support for PING\/PONG packets which are often used to for KeepAlive functionality in websockets. This is particularly important, as browsers tend to be aggressive in killing off these connections.<\/p>\n<p>So, here&#8217;s a quick complete example of Gorilla Websockets in golang, with similar functionality to that I posted previously. It simply echos everything it receives back to the client. First the golang code:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\npackage main\r\n\r\nimport (\r\n        &quot;github.com\/gorilla\/websocket&quot;\r\n        &quot;net\/http&quot;\r\n        &quot;fmt&quot;\r\n)\r\n\r\nvar upgrader = websocket.Upgrader{\r\n    ReadBufferSize:  1024,\r\n    WriteBufferSize: 1024,\r\n}\r\n\r\nfunc print_binary(s &#x5B;]byte) {\r\n  fmt.Printf(&quot;Received b:&quot;);\r\n  for n := 0;n &lt; len(s);n++ {\r\n    fmt.Printf(&quot;%d,&quot;,s&#x5B;n]);\r\n  }\r\n  fmt.Printf(&quot;\\n&quot;);\r\n}\r\n\r\nfunc echoHandler(w http.ResponseWriter, r *http.Request) {\r\n    conn, err := upgrader.Upgrade(w, r, nil)\r\n    if err != nil {\r\n        \/\/log.Println(err)\r\n        return\r\n    }\r\n\r\n    for {\r\n        messageType, p, err := conn.ReadMessage()\r\n        if err != nil {\r\n            return\r\n        }\r\n\r\n        print_binary(p)\r\n\r\n        err = conn.WriteMessage(messageType, p);\r\n        if  err != nil {\r\n            return\r\n        }\r\n    }\r\n}\r\n\r\nfunc main() {\r\n  http.HandleFunc(&quot;\/echo&quot;, echoHandler)\r\n  http.Handle(&quot;\/&quot;, http.FileServer(http.Dir(&quot;.&quot;)))\r\n  err := http.ListenAndServe(&quot;:8080&quot;, nil)\r\n  if err != nil {\r\n    panic(&quot;Error: &quot; + err.Error())\r\n  }\r\n}\r\n<\/pre>\n<p>And then the html used to interface with the websocket. Save it in the same directory as the golang program, and access it at: http:\/\/localhost:8080\/filename.html<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n\r\n&lt;html&gt;\r\n&lt;head&gt;\r\n&lt;meta charset=&quot;UTF-8&quot; \/&gt;\r\n&lt;script&gt;\r\n        var serversocket = new WebSocket(&quot;ws:\/\/localhost:8080\/echo&quot;);\r\n\r\n        serversocket.onopen = function() {\r\n                serversocket.send(&quot;Connection init&quot;);\r\n        }\r\n\r\n        \/\/ Write message on receive\r\n        serversocket.onmessage = function(e) {\r\n                document.getElementById('comms').innerHTML += &quot;Received: &quot; + e.data + &quot;&lt;br&gt;&quot;;\r\n        };\r\n\r\n        function senddata() {\r\n                var data = document.getElementById('sendtext').value;\r\n                serversocket.send(data);\r\n                document.getElementById('comms').innerHTML += &quot;Sent: &quot; + data + &quot;&lt;br&gt;&quot;;\r\n        }\r\n\r\n&lt;\/script&gt;\r\n&lt;\/head&gt;\r\n\r\n&lt;body&gt;\r\n        &lt;input id=&quot;sendtext&quot; type=&quot;text&quot; \/&gt;\r\n        &lt;input type=&quot;button&quot; id=&quot;sendBtn&quot; value=&quot;send&quot; onclick=&quot;senddata()&quot;&gt;&lt;\/input&gt;\r\n        &lt;div id='comms'&gt;&lt;\/div&gt;\r\n&lt;\/body&gt;\r\n&lt;\/html&gt;\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I previously posted a quick example of using the standard library websockets API in golang. Unfortunately there are a number of issues that make difficult to use in practice. Notably, it lacks support for PING\/PONG packets which are often used to for KeepAlive functionality in websockets. This is particularly important, as browsers tend to be [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1],"tags":[],"class_list":["post-1819","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1RRoU-tl","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts\/1819","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/comments?post=1819"}],"version-history":[{"count":2,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts\/1819\/revisions"}],"predecessor-version":[{"id":1821,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts\/1819\/revisions\/1821"}],"wp:attachment":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/media?parent=1819"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/categories?post=1819"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/tags?post=1819"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}