Skip to content

Instantly share code, notes, and snippets.

@dsseng
Created December 29, 2018 09:26
Show Gist options
  • Save dsseng/7674ab61906f16d7c3ad59b7c04ed84a to your computer and use it in GitHub Desktop.
Save dsseng/7674ab61906f16d7c3ad59b7c04ed84a to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"math/rand"
"strconv"
"github.com/go-redis/redis"
"github.com/kataras/iris"
"github.com/kataras/iris/websocket"
"github.com/kataras/iris/middleware/logger"
"github.com/kataras/iris/middleware/recover"
)
func main() {
port := strconv.Itoa(rand.Intn(8000) + 1000) // Random port
redisdb := redis.NewClient(&redis.Options{
Addr: "172.17.0.2:6379", // Redis address
Password: "", // no password set
DB: 0, // use default DB
})
sub := redisdb.Subscribe("mychannel1")
subCh := sub.Channel()
defer sub.Close()
app := iris.New()
app.Logger().SetLevel("debug")
app.Use(recover.New())
app.Use(logger.New())
app.Get("/", func(ctx iris.Context) {
// Code from https://codepen.io/matt-west/pen/tHlBb
ctx.HTML(`
<div id="page-wrapper">
<h1>WebSockets Demo</h1>
<div id="status">Connecting...</div>
<ul id="messages"></ul>
<form id="message-form" action="#" method="post">
<textarea id="message" placeholder="Write your message here..." required></textarea>
<button type="submit">Send Message</button>
<button type="button" id="close">Close Connection</button>
</form>
</div>
<style>
*, *:before, *:after {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
html {
font-family: Helvetica, Arial, sans-serif;
font-size: 100%;
background: #333;
}
#page-wrapper {
width: 650px;
background: #FFF;
padding: 1em;
margin: 1em auto;
border-top: 5px solid #69c773;
box-shadow: 0 2px 10px rgba(0,0,0,0.8);
}
h1 {
margin-top: 0;
}
#status {
font-size: 0.9rem;
margin-bottom: 1rem;
}
.open {
color: green;
}
.closed {
color: red;
}
ul {
list-style: none;
margin: 0;
padding: 0;
font-size: 0.95rem;
}
ul li {
padding: 0.5rem 0.75rem;
border-bottom: 1px solid #EEE;
}
ul li:first-child {
border-top: 1px solid #EEE;
}
ul li span {
display: inline-block;
width: 90px;
font-weight: bold;
color: #999;
font-size: 0.7rem;
text-transform: uppercase;
letter-spacing: 1px;
}
.sent {
background-color: #F7F7F7;
}
.received {}
#message-form {
margin-top: 1.5rem;
}
textarea {
width: 100%;
padding: 0.5rem;
font-size: 1rem;
border: 1px solid #D9D9D9;
border-radius: 3px;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1);
min-height: 100px;
margin-bottom: 1rem;
}
button {
display: inline-block;
border-radius: 3px;
border: none;
font-size: 0.9rem;
padding: 0.6rem 1em;
color: white;
margin: 0 0.25rem;
text-align: center;
background: #BABABA;
border-bottom: 1px solid #999;
}
button[type="submit"] {
background: #86b32d;
border-bottom: 1px solid #5d7d1f;
}
button:hover {
opacity: 0.75;
cursor: pointer;
}
</style>
<script>
window.onload = function() {
// Get references to elements on the page.
var form = document.getElementById('message-form');
var messageField = document.getElementById('message');
var messagesList = document.getElementById('messages');
var socketStatus = document.getElementById('status');
var closeBtn = document.getElementById('close');
// Create a new WebSocket.
var socket = new WebSocket('ws://localhost:` + port + `/ws');
// Handle any errors that occur.
socket.onerror = function(error) {
console.log('WebSocket Error: ' + error);
};
// Show a connected message when the WebSocket is opened.
socket.onopen = function(event) {
socketStatus.innerHTML = 'Connected to: ' + event.currentTarget.url;
socketStatus.className = 'open';
};
// Handle messages sent by the server.
socket.onmessage = function(event) {
var message = event.data;
messagesList.innerHTML += '<li class="received"><span>Received:</span>' + message + '</li>';
};
// Show a disconnected message when the WebSocket is closed.
socket.onclose = function(event) {
socketStatus.innerHTML = 'Disconnected from WebSocket.';
socketStatus.className = 'closed';
};
// Send a message when the form is submitted.
form.onsubmit = function(e) {
e.preventDefault();
// Retrieve the message from the textarea.
var message = messageField.value;
// Send the message through the WebSocket.
socket.send(message);
// Add the message to the messages list.
messagesList.innerHTML += '<li class="sent"><span>Sent:</span>' + message + '</li>';
// Clear out the message field.
messageField.value = '';
return false;
};
// Close the WebSocket connection when the close button is clicked.
closeBtn.onclick = function(e) {
e.preventDefault();
// Close the WebSocket.
socket.close();
return false;
};
};
</script>
`)
})
ws := websocket.New(websocket.Config{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
})
ws.OnConnection(func(c websocket.Connection) {
// Read events from browser
c.OnMessage(func(msg []byte) {
// Print the message to the console, c.Context() is the iris's http context.
fmt.Printf("%s sent: %s\n", c.Context().RemoteAddr(), msg)
err := redisdb.Publish("mychannel1", msg).Err()
if err != nil {
panic(err)
}
})
go (func() {
for msg := range subCh {
// Write message back to the client message owner with:
// c.Emit("chat", msg)
// Write message to all except this client with:
c.To(websocket.Broadcast).EmitMessage([]byte(msg.Payload))
// + echo
c.EmitMessage([]byte(msg.Payload))
}
})()
})
app.Get("/ws", ws.Handler())
app.Run(iris.Addr(":"+port), iris.WithoutServerError(iris.ErrServerClosed))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment