154 lines
4.3 KiB
JavaScript
154 lines
4.3 KiB
JavaScript
|
// NOTE: The contents of this file will only be executed if
|
||
|
// you uncomment its entry in "assets/js/app.js".
|
||
|
|
||
|
// Bring in Phoenix channels client library:
|
||
|
import {Socket} from "phoenix"
|
||
|
|
||
|
// And connect to the path in "lib/demo_web/endpoint.ex". We pass the
|
||
|
// token for authentication. Read below how it should be used.
|
||
|
let socket = new Socket("/socket", {params: {token: window.userToken}})
|
||
|
|
||
|
// When you connect, you'll often need to authenticate the client.
|
||
|
// For example, imagine you have an authentication plug, `MyAuth`,
|
||
|
// which authenticates the session and assigns a `:current_user`.
|
||
|
// If the current user exists you can assign the user's token in
|
||
|
// the connection for use in the layout.
|
||
|
//
|
||
|
// In your "lib/demo_web/router.ex":
|
||
|
//
|
||
|
// pipeline :browser do
|
||
|
// ...
|
||
|
// plug MyAuth
|
||
|
// plug :put_user_token
|
||
|
// end
|
||
|
//
|
||
|
// defp put_user_token(conn, _) do
|
||
|
// if current_user = conn.assigns[:current_user] do
|
||
|
// token = Phoenix.Token.sign(conn, "user socket", current_user.id)
|
||
|
// assign(conn, :user_token, token)
|
||
|
// else
|
||
|
// conn
|
||
|
// end
|
||
|
// end
|
||
|
//
|
||
|
// Now you need to pass this token to JavaScript. You can do so
|
||
|
// inside a script tag in "lib/demo_web/templates/layout/app.html.heex":
|
||
|
//
|
||
|
// <script>window.userToken = "<%= assigns[:user_token] %>";</script>
|
||
|
//
|
||
|
// You will need to verify the user token in the "connect/3" function
|
||
|
// in "lib/demo_web/channels/user_socket.ex":
|
||
|
//
|
||
|
// def connect(%{"token" => token}, socket, _connect_info) do
|
||
|
// # max_age: 1209600 is equivalent to two weeks in seconds
|
||
|
// case Phoenix.Token.verify(socket, "user socket", token, max_age: 1_209_600) do
|
||
|
// {:ok, user_id} ->
|
||
|
// {:ok, assign(socket, :user, user_id)}
|
||
|
//
|
||
|
// {:error, reason} ->
|
||
|
// :error
|
||
|
// end
|
||
|
// end
|
||
|
//
|
||
|
// Finally, connect to the socket:
|
||
|
socket.connect()
|
||
|
|
||
|
const draw_graph = (ctx, tbl) => {
|
||
|
let tmax=0
|
||
|
for(v of tbl) {
|
||
|
tmax = Math.max(v, tmax)
|
||
|
}
|
||
|
ctx.fillStyle = "#fff"
|
||
|
ctx.strokeStyle = "#00f"
|
||
|
ctx.fillRect(0, 0, 400, 200)
|
||
|
ctx.lineWidth = 2
|
||
|
for(let i=0; i < tbl.length; ++i) {
|
||
|
ctx.beginPath();
|
||
|
ctx.moveTo(200*Math.sqrt(i/200), 200)
|
||
|
ctx.lineTo(200*Math.sqrt(i/200),
|
||
|
200-(200*Math.sqrt(tbl[i]/tmax)))
|
||
|
ctx.stroke();
|
||
|
|
||
|
}
|
||
|
ctx.fillStyle = "#000"
|
||
|
for (let i of [0, 2, 5, 10, 25, 50, 100, 200, 500]) {
|
||
|
ctx.fillText(i, 200*Math.sqrt(i/200), 10)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
let interval = null
|
||
|
const ping = () => {
|
||
|
const canvas = document.querySelector("#ping_canvas")
|
||
|
ctx = canvas.getContext("2d")
|
||
|
const tbl = new Array(400).fill(0)
|
||
|
return () => {
|
||
|
let d1 = Date.now();
|
||
|
let id = (Math.random()*0xffffffff).toString(16)
|
||
|
channel.push("ping", {id})
|
||
|
.receive("ok", resp => {
|
||
|
if (resp.id != id) {
|
||
|
console.log("ERROR :'(", id, resp);
|
||
|
if (interval) {
|
||
|
clearInterval(interval)
|
||
|
interval = null
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
let t = Date.now()-d1
|
||
|
//console.log("PING!", t)
|
||
|
tbl[Math.min(t, 399)] += 1
|
||
|
draw_graph(ctx, tbl)
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Now that you are connected, you can join channels with a topic.
|
||
|
// Let's assume you have a channel with a topic named `room` and the
|
||
|
// subtopic is its id - in this case lobby:
|
||
|
let channel = socket.channel("room:lobby", {})
|
||
|
|
||
|
channel.join()
|
||
|
.receive("ok", resp => {
|
||
|
console.log("Joined successfully", resp)
|
||
|
interval = setInterval(ping(), 100)
|
||
|
})
|
||
|
.receive("error", resp => {
|
||
|
if (interval) {
|
||
|
clearInterval(interval)
|
||
|
interval = null
|
||
|
}
|
||
|
console.log("Unable to join", resp)
|
||
|
})
|
||
|
|
||
|
const input_fib = document.querySelector("#in_fib")
|
||
|
const btn_fib = document.querySelector("#btn_fib")
|
||
|
const res_div = document.querySelector("#results")
|
||
|
let queries = {}
|
||
|
|
||
|
btn_fib.onclick = evt => {
|
||
|
console.log(input_fib.value)
|
||
|
channel.push("fib", {query: input_fib.value})
|
||
|
.receive("ok", resp => {
|
||
|
const elem = document.createElement("div")
|
||
|
elem.innerHTML = "Waiting... " + input_fib.value
|
||
|
res_div.prepend(elem)
|
||
|
queries[resp.id] = elem
|
||
|
console.log("OK", resp)
|
||
|
})
|
||
|
.receive("error", err => {
|
||
|
console.log("Error", resp)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
channel.on("response", resp => {
|
||
|
if (queries[resp.id]) {
|
||
|
const elem = queries[resp.id]
|
||
|
elem.innerHTML = resp.query + " => " + resp.result
|
||
|
} else {
|
||
|
console.log("Query not found :'''(((")
|
||
|
}
|
||
|
console.log(resp)
|
||
|
})
|
||
|
|
||
|
export default socket
|