// 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": // // // // 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