Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate ServerConnection and ClientConnection #4078

Merged

Conversation

kwvanderlinde
Copy link
Collaborator

@kwvanderlinde kwvanderlinde commented May 20, 2023

Identify the Bug or Feature request

Implements #4076

Description of the Change

The change basically follows the plan set in #4076, moving methods and fields around according to the actual responsibilities for ServerConnection and ClientConnection. The goal was to leave the usage as-is, only adjusting names and the location of methods and fields to align with expectations and to make the clientserver package clearer. The commits detail exactly what moved where, and it may be easier to see the changes to clientserver in the commit diffs rather than the full PR diff.

There was one usage change, which was to remove message dispatching from ServerConnection. It was only ever used with a single ServerMessageHandler anyways, which was set immediately after the creation of the ServerConnection. Now we instead require the handler to be passed as a constructor parameter, and then register it on ClientConnection directly. This is simpler than having the ClientConnection dispatch to ServerConnection and then ServerConnection dispatch to the ServerMesageHandler. Removing the dispatching also enabled a full separation of ServerConnection and ClientConnection without requiring more drastic refactorings.

After the rename, we're left with these types and responsibilities:

  • Connection (used to be ClientConnection) decorates and opens connections, adding message sending and receiving capabilities.
  • Server (used to be ServerConnection) waits for clients to connect, creates Connection objects to represent them, and broadcasts messages to selected clients over the corresponding Connection.

Possible Drawbacks

Should be none, unless I messed up and change behaviour during one of the steps.

Documentation Notes

N/A

Release Notes

  • Cleaned up the client-server code

This change is Reviewable

Both `SocketClientConnection` and `WebRTCClientConnection` create a message-sending thread and pass a reference to
themselves along. But the thread classes are non-static inner classes, so they already implicitly have such a
reference. More importantly, some `Connection`/`AbstractConnection` methods are only public so that these threads can
access them via the explicit reference, whereas the implicit reference would allow for protected methods to be used
instead.
Akin to `AbstractServerConnection`, we now have `AbstractClientConnection` which can provide common functionality that
is specific to `ClientConnection` implementations. The status quo is that such functionality lives in
`AbstractConnection`, thus providing `ServerConnection` functionality it does not need.

`AbstractClientConnection` will be filled in later.
The `Connection` methods `addMessage()`, `hasMoreMessages()` and `nextMessages()` were only used internally for
`ClientConnection `implementations, through and supported by `AbstractConnection`. The methods are no longer publicly
exposed, and the implementations have been moved out of `AbstractConnection` into `AbstractClientConnection`
`AbstractConnection` provided utility methods for reading messages from a stream, decompressing them, and dispatching to
handlers. This has all been moved into `AbstractClientConnection` instead.
`DiconnectHandler` used to deal in `AbstractConnection` despite only ever being used with `ClientConnection`
objects. Additionally, only `ClientConnection` can fire disconnection events, so the methods for registering
`DisconnectHandler` has been moved from `Connection` to `ClientConnection`. `Connection.fireDisconnect()` is actually an
internal utility method and is no longer exposed publicly.
Only `ClientConnection` is able to notify `ActivityListener` since only `ClientConnection` is responsible for reading
and writing messages. The registration methods have been moved from `Connection` to `ClientConnection`, with the
`notifyListeners()` helper method being also moved from `AbstractConnection` to `AbstractClientConnection`.
`ServerConnection` was only ever used with one handler (`ServerMessageHandler`), which was set immediately after the
`ServerConnection` was created, and would not change through the lifetime of the `ServerConnection`. Additionally,
`AbstractServerConnection`'s nature as a `MessageHandler` was only for piping messages from `ClientConnection` into the
`ServerConnection`'s own dispatching mechanism.

So instead of relying on dispatching in `AbstractServerConnection`, we now require a `MessageHandler` to be passed at
the time of creation, and we attach it to each `ClientConnection` as they are created. This means only
`ClientConnection` need to know about message dispatching. So the registration methods could be moved out of
`Connection` into `ClientConnection`, and the dispatching implementation out of `AbstractConnection` into
`AbstractClientConnection`.
Everything of use has been removed from `AbstractConnection`, so there is no need to keep this as a common base for
`AbstractServerConnection` and `AbstractClientConnection`.
Now `ServerConnection` and `ClientConnection` have their own `open()` and `close()` methods. In the case of
`ServerConnection`, the method was renamed to `start()` to indicate its purpose more clearly, as it is not related at
all to the opening of connections as in `ClientConnection`.

Both `ServerConnection` and `ClientConnection` now extend `AutoCloseable`, as their `close()` methods have the same
expectations.
The `Connection` interface has already had everything removed from it, and it is not directly used by callers
anymore. As it no longer provides any value, it has been removed.
The `sendMessage()` overloads in `ClientConnection` and `ServerConnection` allow the channel to be
omitted. Implementations simply delegate to the other overload by providing a `null` channel. As this is the required
behaviour, this is better done in the interface via a `default` method.
This type does not represent a connection, but instead represents a server capable of connecting to any number of
clients. The new name reflects this fact.
Also the package name has been changed from `client` to `connection`.

This type represents a connection between a server and a client. It is to be used both server-side and client-side, and
so the use of the term "client" only distracts from its purpose. Similarly, the package name would suggest some
client-side utilities, but in reality contains implementations for connections.
@cwisniew cwisniew added this pull request to the merge queue May 21, 2023
Merged via the queue into RPTools:develop with commit a25a1c3 May 21, 2023
4 checks passed
@kwvanderlinde kwvanderlinde deleted the refactor/4076-separate-connection-types branch May 21, 2023 06:17
@cwisniew cwisniew added the code-maintenance Adding/editing javadocs, unit tests, formatting. label May 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
code-maintenance Adding/editing javadocs, unit tests, formatting.
Projects
Status: Merged
Development

Successfully merging this pull request may close these issues.

None yet

2 participants