tiny
tiny copied to clipboard
Connecting to same server multiple times
I'm using tiny with soju irc bouncer in single stream mode.
So I connect to my server two times with, a different login to reach libera or oftc : eoli3n/irc.oftc.net
and eoli3n/irc.libera.chat
.
It seems problematic to tiny.
A solution would be to be able to set a name
in tiny config like
- addr: my_server.domain.com
name: libera
realname: eoli3n
nicks:
- eoli3n
sasl:
username: 'eoli3n/irc.libera.chat'
- addr: my_server.domain.com
name: oftc
realname: eoli3n
nicks:
- eoli3n
sasl:
username: 'eoli3n/irc.oftc.net'
After more test, it works well, but then, tiny concatenate both connection. So I can just join channels for the first one in the my_server.domain.com
tab. Any workaround ?
If you set an alias does it work? I don't think name
is a config.
e.g
- addr: my_server.domain.com
alias: libera
...
Worked like a charm ! Thanks
Oh sorry, I mistested With that config:
- addr: bouncer.fr
alias: libera
...
sasl:
username: 'eoli3n/irc.libera.chat'
- addr: bouncer.fr
alias: oftc
...
sasl:
username: 'eoli3n/irc.oftc.net'
When I start tiny, I can see a "libera" buffer, but not the "oftc" one.
Thanks for reporting, @eoli3n. From tiny's point of view, you're trying to connect to the same server (the bouncer) multiple times, which is currently not supported.
I'll take a look into this soon.
I think I know how to implement this, but it requires refactoring some of the most central types. It will be fairly straightforward, but a lot of code will have to change, and I may not have time any time soon to do this myself. Let me explain the idea and maybe someone can pick it up.
Background
In tiny, clients do not manipulate the TUI directly. Instead they write connection events to a channel. The receiving end then does the TUI updates.
The receiving end of a connection channel is the tokio task defined in tiny::conn::task
. This task updates the TUI when it receives a network event. Each connectin (aka. client, libtiny_client::Client
) gets one task, a task only handles on connection.
To determine which TUI tabs to update it needs to know the client's "name". The name is currently the server address (e.g. irc.oftc.net
). Client
has a method get_serv_name()
to get a connection's name.
TUI tabs hold their connection's name, in the src
field of Tab
. So when we receive a connection event from a Client
, we use the Client
's name to find the tabs to update. (we compare the name with Tab
's src
field)
Note that "alias" is not used anywhere. It's only used when rendering a tab in a tab line. When it's available, we use it instead of the tab's client's name (which, as mentioned above, a tab holds in its src
field).
Tab
's src
field is used to route a message sent by the user in a tab to the right connection. It's done in a similar way, we just search all Client
s to find the one with the right name.
Problem
Using server address as server name means if we create multiple Client
s with same address (hence same "name"), there will be confusion when we receive an events from those connections. Because they will all have same the same name, we will update the same tabs for different connections.
You can observe this with this config:
servers:
- addr: irc.oftc.net
port: 6697
tls: true
realname: yourname
nicks: [tiny_user]
join: ["#tiny"]
- addr: irc.oftc.net
port: 6697
tls: true
realname: yourname
nicks: [tiny_user_2]
join: ["#tiny"]
If you run with this config, you'll see that same server and channel tabs are updated for both of these connections. E.g. you see channel subject twice, each incoming message to the channel twice etc.
Plan
Clearly we can't use server address to map a connection to its TUI tabs, or the other way around, as we want to be able to have multiple connections with same server address.
I suggest we use a unique number (say, a usize
) for each connection created. We maintain a counter of numbers created so far. Every time we create a new connection, we bump that number, and use the previous value as the unique number of the connection.
When creating the Client
, we pass the unique connection number to the Client
. Same when creating the TUI
tab.
Let's call this unique number ServerId
.
For every MsgSource
and MsgTarget
variant with a serv
field, we add a new field serv_id: ServerId
.
After that, we use the serv_id
fields of MsgSource
and MsgTarget
when finding Client
of a tab in tiny::ui::task
, and TUI tab of a Client
event in tiny::conn::task
.
With these changes it will be possible to connect to a server multiple times. We can then improve on this by requesting user to specify an alias when connecting to a same server multiple times. It can be done later in a separate PR.