Я следовал за примером http-kit websockets и позже застрял, пытаясь найти идиоматический c способ сопоставления каналов WS пользователям на бэкэнде.
У меня есть попытался проверить объект org.httpkit.server.AsyncChannel, используя отражение Java, и получил следующие атрибуты:
| :name | :return-type | :declaring-class | :parameter-types | :exception-types | :flags |
|---------------------------------+----------------------+---------------------------------+----------------------------------------------------------------+-----------------------+---------------------|
| chunkSize | java.nio.ByteBuffer | org.httpkit.server.AsyncChannel | [int] | [] | #{:private :static} |
| firstWrite | void | org.httpkit.server.AsyncChannel | [java.lang.Object boolean] | [java.io.IOException] | #{:private} |
| isClosed | boolean | org.httpkit.server.AsyncChannel | [] | [] | #{:public} |
| isWebSocket | boolean | org.httpkit.server.AsyncChannel | [] | [] | #{:public} |
| messageReceived | void | org.httpkit.server.AsyncChannel | [java.lang.Object] | [] | #{:public} |
| onClose | void | org.httpkit.server.AsyncChannel | [int] | [] | #{:public} |
| org.httpkit.server.AsyncChannel | | org.httpkit.server.AsyncChannel | [java.nio.channels.SelectionKey org.httpkit.server.HttpServer] | [] | #{:public} |
| pingReceived | void | org.httpkit.server.AsyncChannel | [byte<>] | [] | #{:public} |
| readable | clojure.lang.Keyword | org.httpkit.server.AsyncChannel | [int] | [] | #{:private :static} |
| reset | void | org.httpkit.server.AsyncChannel | [org.httpkit.server.HttpRequest] | [] | #{:public} |
| send | boolean | org.httpkit.server.AsyncChannel | [java.lang.Object boolean] | [java.io.IOException] | #{:public} |
| sendHandshake | void | org.httpkit.server.AsyncChannel | [java.util.Map] | [] | #{:public} |
| serverClose | boolean | org.httpkit.server.AsyncChannel | [int] | [] | #{:public} |
| setCloseHandler | void | org.httpkit.server.AsyncChannel | [clojure.lang.IFn] | [] | #{:public} |
| setPingHandler | void | org.httpkit.server.AsyncChannel | [clojure.lang.IFn] | [] | #{:public} |
| setReceiveHandler | void | org.httpkit.server.AsyncChannel | [clojure.lang.IFn] | [] | #{:public} |
| toString | java.lang.String | org.httpkit.server.AsyncChannel | [] | [] | #{:public} |
| writeChunk | void | org.httpkit.server.AsyncChannel | [java.lang.Object boolean] | [java.io.IOException] | #{:private} |
nil
, которые, кажется, не содержат четких идентификаторов, включая .toString
:
user=> (.toString ch)
"/0:0:0:0:0:0:0:1:3000<->/0:0:0:0:0:0:0:1:54538"
Единственная идея, которую я мог придумать, заключается в следующем:
1) Сохранить connect!
функцию как есть:
(defonce channels (atom #{}))
(defn connect! [channel]
(log/info "channel open" channel)
(swap! channels conj channel))
2) Обновить клиент WebSocket для отправки JWT или вызов идентификатора сеанса в качестве первого сообщения сразу после установления соединения WS, которое позволяет сопоставить этот (уже установленный) канал с идентификатором (JWT или идентификатором сеанса вызова), который может идентифицировать пользователя.
Имеет ли это смысл при все? Или это большой антипаттерн и нарушение WS RFC? Извините, я не работал с WebSockets на таком низком уровне раньше.