romshark / webwire-go Goto Github PK
View Code? Open in Web Editor NEWA transport independent asynchronous duplex messaging library for Go
License: MIT License
A transport independent asynchronous duplex messaging library for Go
License: MIT License
Currently a custom error type webwire.Error is used in the OnRequest hook, which is fine but consider using the default Go error interface as this would ease the use of the library. When a non-webwire.Error is returned the transmitted reply error could probably have some default code value.
Issue #11 already covers the autoconnect feature but misses one important case:
When the client connects to the server just to listen to server-side signals - the connection could get lost at some point (due to a server reboot for example) and the user-code will assume, that there's just nothing happening on the server, but in reality the server just won't send the signals due to the client being disconnected whole the time.
In such a case it's very important for the client to try to reconnect in the background as soon as the connection is lost to ensure maximum uptime.
As of #23 the maximum number of concurrently executed handlers can be limited globally affecting all connected clients, though it might make sense to also allow limiting the number of concurrently executed handlers per client as well.
In the case of TLS handshake errors (such as a certificate verification error due to untrusted authority on a self-signed certificate), the client must immediately return an error aborting the automatic connection establishment process.
The automatic connection establishment process enters an infinite loop trying to connect indefinitely.
InsecureSkipVerify
to false
in the TLS configuration and watch it trying to connect indefinitely.Currently, requests performed one after the other will arrive at the server in serial order, though the order is broken when in the meanwhile the server is unavailable and the client is trying to reconnect before sending out accumulated requests. I suggest making the client retain the order the requests were initially made in to avoid unsynchronized delivery.
Test hot server-side handling of invalid & unparsable, protocol violating messages such as messages with invalid type identifiers and mismatching length flags to ensure the server gracefully handles those.
Currently, there's no way to implement your own session key generator which is rather restrictive. It'd be nice to have the possibility to provide your own generator or use the built-in generator by default.
Add support for cancellation and deadlines through context.Context in methods such as client.Request
Calling client.Close()
on a client agent while processing it's request causes an internal server error, because the response cannot be sent due to the client being disconnected immediately.
client.Close()
must defer closing the client agent until all work on that client agent is finished.
Add support for custom subprotocols. Currently, sub-protocols have to be implemented using the namespacing feature, where different types of requests/signals have different names, which is fine so far but webwire doesn't distinguish between different subprotocols at all, it should at least avoid connecting to a webwire server that doesn't speak it's language.
That will simplify life for those who use both this library and gorilla/websocket directly.
http://keepachangelog.com/
Releases are nice, but not enough โ they are not visible when the library is already cloned or vendored. Since both use markdown for formatting, they can be simply copied and pasted.
Currently only UTF8 and UTF16 text as well as plain binary messages are supported, so theoretically native support for JSON could prove handy.
Currently sessions are silently disabled if one of the sessions related hooks is undefined which is rather unintuitive. Consider adding a default built-in session storage implementation to be used by default if all sessions related hooks are undefined. This would improve usability and help newcomers getting started faster.
Currently the server does handle multiple connections concurrently but it processes the messages sequentially. Requests and signals of a single client are always processed in the goroutine handling that particular client, this could turn out critical, because even if we spawn goroutines manually in the OnRequest
handler for example - we'd still block other requests when waiting for the blocking one to return a response. It'd therefore make sense to move the processing of messages into separate goroutines and ideally make this feature optional by providing a server option for disabling concurrent message processing.
Make the webwire client automatically connect to the server right after initialization and make it optionally automatically reconnect on connection loss
There's currently no way to list all connections (aka client agents) belonging to a certain session. The only function that comes close to solving this issue is SessionRegistry.SessionConnections though it returns only the number of connections of the given session. Wouldn't it make more sense to return []*Client
instead?
Currently the request-reply topology works in a single direction: client -> server which is fine for now, but shouldn't we consider adding support for duplex request-reply to also be able to send requests from the server to the client?
The webwire server should keep track of currently processed requests and signals and wait for them to finish before closing to avoid data loss and errors. During a requested shutdown new connections, requests and signals must not be accepted.
For use webwire on https we need to do a lot of action, as in example. It will be more convenient to have a constructor that will accept, in addition to the ServerImplementation and ServerOptions, a certificate with a key and listen https connections, like:
func NewSecureServer(
implementation ServerImplementation,
opts ServerOptions,
certFile,
keyFile string,
)
Sessions must get a new field "lastUse" of date type to indicate when a particular session was lastly updated. This is important for the session manager to know whether a session is still relevant during garbage collection.
The client should provide an option for multiple underlying connections to be used for potentially increased throughput and lower latencies in network environments with high packet loss. Messages should be distributed fan-out round-robin on the available connections.
Ideally, the number of underlying connections should be dynamically adjustable.
The webwire client currently utilizes just one single websocket connection. In network environments where packet loss is small having an HTTP/2-style multiplexed single TCP/IP connection (which the underlying WebSocket basically is) is ideal, though in network environments with high packet loss HTTP/1.1-style multiple individual TCP/IP connections should, in theory, provide better throughput and latency due to the TCP congestion-avoidance algorithm, which could potentially cause artificial slowdowns resulting in unsaturated network usage, at the cost of memory usage and higher connection establishment latency.
To be discussed
To be discussed
The server must also support this feature by providing an option of a maximum number of acceptable connections for a single client, though I'm not quite sure whether this is the case.
The client agent method client.Session()
should return a copy of the session object though there is a problem with it returning a shallow copy of the session info map. This could lead to unsychronized access to the session info map as both session objects reference the same info object but can be owned by different goroutines.
Concurrent access to the session object in the client by both the reading goroutine created during the connection setup and the writing goroutine calling the API (when calling the client.RestoreSession method for example) causes a data race!
Synchronize read-write access to the internal client session object.
Currently a session can only be assigned to a single connection, though sessions should accept multiple simultaneous connections to support authentication across multiple browser tabs/windows of the same domain.
Ease this restriction by adding an option for the maximum number of simultaneous connections associatable with a single session.
Are there already any performance benchmarking results available?
Request message requires a payload even though a payload shouldn't be obligatory. In some cases a request name is sufficient. For example if we just want to notify the server about an event like client.Request("event_a_happend", wwr.Payload{})
then we won't need a payload, but currently we have to provide a payload otherwise an error is returned indicating that the request message couldn't be parsed.
WEBWIRE_ERR: 2018/05/15 18:26:36 serverHttp.go:72: Failed parsing message: Invalid request message, too short
When the session is closed by the client offline due a temporarily interrupted connection, then the client will just remove and forget it while it will remain open on the server even when the connection is reestablished.
The client should be made responsible for cleaning up when a session was closed offline. It must remember the session key and request the destruction of the closed sessions as soon as the connection is reestablished, to reduce server-load.
Use *log.Logger
instead of io.Writer
for logging, it allows the library user to set custom logging flags and prefixes. Currently this is not possible and the default prefixes are used like: WARNING:
and ERROR:
, though we'd like to differentiate between error logs produced by webwire and our own code.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.