mirror of
https://github.com/matrix-org/sliding-sync.git
synced 2025-03-10 13:37:11 +00:00
Flesh out client, fix session management
- Request first 100 rooms, with placeholder icons - Add a `http.FileServer` for everything under `/client` for images. - Sessions are only 400d if they provide a `?pos=` with the session ID.
This commit is contained in:
parent
3f9794ef33
commit
415575d942
@ -2,12 +2,36 @@
|
||||
<head>
|
||||
<title>Sync v3 experiments</title>
|
||||
<script>
|
||||
let restart = false;
|
||||
const doSyncLoop = async(accessToken) => {
|
||||
let activeSessionId;
|
||||
const roomIdToRoom = {};
|
||||
const roomIdToDiv = {}; // cached innerHTML
|
||||
const render = (container, rooms) => {
|
||||
// TODO: don't nuke all cells
|
||||
while (container.firstChild) {
|
||||
container.removeChild(container.firstChild);
|
||||
}
|
||||
rooms.forEach((r) => {
|
||||
roomIdToRoom[r.room_id] = r;
|
||||
const template = document.getElementById("roomCellTemplate");
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template#avoiding_documentfragment_pitfall
|
||||
const roomCell = template.content.firstElementChild.cloneNode(true);
|
||||
roomCell.addEventListener("click", (e) => {
|
||||
console.log(r, e);
|
||||
});
|
||||
roomIdToDiv[r.room_id] = roomCell;
|
||||
roomCell.getElementsByClassName("roomName")[0].textContent = r.name;
|
||||
container.appendChild(roomCell);
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
const doSyncLoop = async(accessToken, sessionId) => {
|
||||
console.log("Starting sync loop. Active: ", activeSessionId, " this:", sessionId);
|
||||
let currentPos;
|
||||
let rooms = [];
|
||||
while (!restart) {
|
||||
let resp = await doSyncRequest(accessToken, currentPos, [0,9]);
|
||||
while (sessionId === activeSessionId) {
|
||||
let resp = await doSyncRequest(accessToken, currentPos, [0,99], sessionId);
|
||||
currentPos = resp.pos;
|
||||
if (!resp.ops) {
|
||||
continue;
|
||||
@ -60,28 +84,12 @@
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let output = "";
|
||||
rooms.forEach((r) => {
|
||||
if (!r) {
|
||||
output += "_____\r\n";
|
||||
return;
|
||||
render(document.getElementById("listContainer"), rooms);
|
||||
}
|
||||
output += (r.name || r.room_id) + "\r\n";
|
||||
})
|
||||
|
||||
// re-render the rooms array
|
||||
console.log(rooms);
|
||||
console.log(output);
|
||||
document.getElementById("list").textContent = output;
|
||||
}
|
||||
console.log("restarting");
|
||||
document.getElementById("list").textContent = "";
|
||||
restart = false;
|
||||
doSyncLoop(accessToken);
|
||||
console.log("active session: ", activeSessionId, " this session: ", sessionId, " terminating.");
|
||||
}
|
||||
// accessToken = string, pos = int, ranges = [2]int e.g [0,99]
|
||||
const doSyncRequest = async (accessToken, pos, ranges) => {
|
||||
const doSyncRequest = async (accessToken, pos, ranges, sessionId) => {
|
||||
let resp = await fetch("/_matrix/client/v3/sync" + (pos ? "?pos=" + pos : ""), {
|
||||
method: "POST",
|
||||
headers: {
|
||||
@ -89,7 +97,8 @@
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
rooms: [ranges]
|
||||
rooms: [ranges],
|
||||
session_id: (sessionId ? sessionId : undefined),
|
||||
})
|
||||
});
|
||||
let respBody = await resp.json();
|
||||
@ -98,12 +107,17 @@
|
||||
}
|
||||
|
||||
window.addEventListener('load', (event) => {
|
||||
const storedAccessToken = window.localStorage.getItem("accessToken");
|
||||
if (storedAccessToken) {
|
||||
document.getElementById("accessToken").value = storedAccessToken;
|
||||
}
|
||||
document.getElementById("syncButton").onclick = () => {
|
||||
const accessToken = document.getElementById("accessToken").value;
|
||||
doSyncLoop(accessToken);
|
||||
window.localStorage.setItem("accessToken", accessToken);
|
||||
doSyncLoop(accessToken, activeSessionId);
|
||||
}
|
||||
document.getElementById("resetButton").onclick = () => {
|
||||
restart = true;
|
||||
activeSessionId = new Date().getTime() + "";
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@ -112,8 +126,14 @@
|
||||
<div>
|
||||
<input id="accessToken" type="password" placeholder="matrix.org access token" />
|
||||
<input id="syncButton" type="button" value="Sync" />
|
||||
<input id="resetButton" type="button" value="Reset" />
|
||||
<p id="list" style="white-space: pre;"></p>
|
||||
<input id="resetButton" type="button" value="New Session" />
|
||||
<div id="listContainer" ></div>
|
||||
<template id="roomCellTemplate">
|
||||
<div style="padding: 5px; display: flex; align-items: center;">
|
||||
<img src="/client/placeholder.svg" style="width: 32px; height: 32px;"/>
|
||||
<span class="roomName"> </span>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
5
client/placeholder.svg
Normal file
5
client/placeholder.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.0" width="150" height="150">
|
||||
<path fill="#ccc" d="M 104.68731,56.689353 C 102.19435,80.640493 93.104981,97.26875 74.372196,97.26875 55.639402,97.26875 46.988823,82.308034 44.057005,57.289941 41.623314,34.938838 55.639402,15.800152 74.372196,15.800152 c 18.732785,0 32.451944,18.493971 30.315114,40.889201 z"/>
|
||||
<path fill="#ccc" d="M 92.5675 89.6048 C 90.79484 93.47893 89.39893 102.4504 94.86478 106.9039 C 103.9375 114.2963 106.7064 116.4723 118.3117 118.9462 C 144.0432 124.4314 141.6492 138.1543 146.5244 149.2206 L 4.268444 149.1023 C 8.472223 138.6518 6.505799 124.7812 32.40051 118.387 C 41.80992 116.0635 45.66513 113.8823 53.58659 107.0158 C 58.52744 102.7329 57.52583 93.99267 56.43084 89.26926 C 52.49275 88.83011 94.1739 88.14054 92.5675 89.6048 z" />
|
||||
</svg>
|
After Width: | Height: | Size: 918 B |
@ -86,8 +86,11 @@ func (h *SyncLiveHandler) serve(w http.ResponseWriter, req *http.Request) error
|
||||
}
|
||||
}
|
||||
}
|
||||
if requestBody.SessionID == "" {
|
||||
requestBody.SessionID = DefaultSessionID
|
||||
}
|
||||
|
||||
conn, err := h.setupConnection(req, &requestBody)
|
||||
conn, err := h.setupConnection(req, &requestBody, req.URL.Query().Get("pos") != "")
|
||||
if err != nil {
|
||||
hlog.FromRequest(req).Err(err).Msg("failed to get or create Conn")
|
||||
return err
|
||||
@ -127,7 +130,7 @@ func (h *SyncLiveHandler) serve(w http.ResponseWriter, req *http.Request) error
|
||||
// setupConnection associates this request with an existing connection or makes a new connection.
|
||||
// It also sets a v2 sync poll loop going if one didn't exist already for this user.
|
||||
// When this function returns, the connection is alive and active.
|
||||
func (h *SyncLiveHandler) setupConnection(req *http.Request, syncReq *Request) (*Conn, error) {
|
||||
func (h *SyncLiveHandler) setupConnection(req *http.Request, syncReq *Request, containsPos bool) (*Conn, error) {
|
||||
log := hlog.FromRequest(req)
|
||||
var conn *Conn
|
||||
|
||||
@ -142,7 +145,7 @@ func (h *SyncLiveHandler) setupConnection(req *http.Request, syncReq *Request) (
|
||||
}
|
||||
|
||||
// client thinks they have a connection
|
||||
if syncReq.SessionID != "" {
|
||||
if containsPos {
|
||||
// Lookup the connection
|
||||
// we need to map based on both as the session ID isn't crypto secure but the device ID is (Auth header)
|
||||
conn = h.ConnMap.Conn(ConnID{
|
||||
@ -202,7 +205,7 @@ func (h *SyncLiveHandler) setupConnection(req *http.Request, syncReq *Request) (
|
||||
// to check for an existing connection though, as it's possible for the client to call /sync
|
||||
// twice for a new connection and get the same session ID.
|
||||
conn, created := h.ConnMap.GetOrCreateConn(ConnID{
|
||||
SessionID: DefaultSessionID,
|
||||
SessionID: syncReq.SessionID,
|
||||
DeviceID: deviceID,
|
||||
}, v2device.UserID)
|
||||
if created {
|
||||
@ -210,7 +213,6 @@ func (h *SyncLiveHandler) setupConnection(req *http.Request, syncReq *Request) (
|
||||
} else {
|
||||
log.Info().Str("conn_id", conn.ConnID.String()).Msg("using existing connection")
|
||||
}
|
||||
syncReq.SessionID = conn.ConnID.SessionID
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
|
26
v3.go
26
v3.go
@ -3,7 +3,6 @@ package syncv3
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
@ -31,7 +30,7 @@ func (s *server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
h.ServeHTTP(w, req)
|
||||
}
|
||||
|
||||
func jsClient(file []byte) http.HandlerFunc {
|
||||
func allowCORS(next http.Handler) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, req *http.Request) {
|
||||
if req.Method == "OPTIONS" {
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
@ -40,29 +39,20 @@ func jsClient(file []byte) http.HandlerFunc {
|
||||
w.WriteHeader(200)
|
||||
return
|
||||
}
|
||||
// TODO: remove when don't need live updates
|
||||
jsFile, err := ioutil.ReadFile("client.html")
|
||||
if err != nil {
|
||||
logger.Fatal().Err(err).Msg("failed to read client.html")
|
||||
next.ServeHTTP(w, req)
|
||||
}
|
||||
w.WriteHeader(200)
|
||||
w.Write(jsFile)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// RunSyncV3Server is the main entry point to the server
|
||||
func RunSyncV3Server(h http.Handler, bindAddr string) {
|
||||
|
||||
jsFile, err := ioutil.ReadFile("client.html")
|
||||
if err != nil {
|
||||
logger.Fatal().Err(err).Msg("failed to read client.html")
|
||||
}
|
||||
|
||||
// HTTP path routing
|
||||
r := mux.NewRouter()
|
||||
r.Handle("/_matrix/client/v3/sync", h)
|
||||
r.HandleFunc("/client", jsClient(jsFile)).Methods("GET", "OPTIONS", "HEAD")
|
||||
r.PathPrefix("/client/").HandlerFunc(
|
||||
allowCORS(
|
||||
http.StripPrefix("/client/", http.FileServer(http.Dir("./client"))),
|
||||
),
|
||||
)
|
||||
|
||||
srv := &server{
|
||||
chain: []func(next http.Handler) http.Handler{
|
||||
@ -73,7 +63,7 @@ func RunSyncV3Server(h http.Handler, bindAddr string) {
|
||||
Int("status", status).
|
||||
Int("size", size).
|
||||
Dur("duration", duration).
|
||||
Str("since", r.URL.Query().Get("since")).
|
||||
Str("path", r.URL.Path).
|
||||
Msg("")
|
||||
}),
|
||||
hlog.RemoteAddrHandler("ip"),
|
||||
|
Loading…
x
Reference in New Issue
Block a user