Distributed Erlang, how do I generate unique node names? - java

I am building an Erlang server-client program. The server is written in Erlang OTP and the client in Java with Jinterface.
When creating a Jinterface connection I have to set a node name in the constructor OtpNode(). The problem is that this is done before connecting to the server (obviously), but each client must have unique names. If a client tries to connect to the server when a client with the same name is already connected, then the new connection fails.
How do I solve this? My first taught was to have a node without name or let the server supply the client with a name, but that does not seems to work...

Sounds like a job for UUID.randomUUID().
"UUID" stands for "Universally Unique ID", and it allows you to assume that any two clients will generate a different UUID without needing to contact each other.

Related

ChatServer in java

I did a simple chatserver in the java ... I'm wondering about adding a username to a chat that you need to enter when you enter chat. Also, I do not understand how private messages are sent only to the addressee
If the destination is not logged in to the chat server, the error message should be sent to the sender
Each message sent by the server to the client must be accompanied by the name of the original sender and the time when the message was sent.
Java Code ---> https://dijaspora24.info/?page_id=4123
I am not going to show the implementation, since it's a big problem to solve here. However, I will give an idea of how to implement this.
I assume you know how to connect a client to a server (for example by using ServerSocket and Socket).
First, to add the username of a connected client, the server simply has to force the client enter a string to the server as the first thing when it connects to the server.
Second, create a Map to store all clients, where key is the username entered and value is the socket.
Third, when a client want to send a message to another client, some format must be used to send a string that is understandable by the server. When sending a string to another client, the username of the receiving client must be within the string. When the server receives the string, it extracts the username of the receiving client's username and locates the client in the Map by its key. As mentioned, the value of the Map element is the socket instance of the client you want to send to.
To make all of this possible, a thread must be used for each client that listens for input from each client.

How could I send a string message to a specific client from a server using sockets in java?

I want to send data to my connected clients, but I want to send the message only to one specific user. I don't know how to accomplish this. Do I have to use the client's IP address or what? I'm programming in Java with sockets.
you need to add connected connection in some collection.
Socket client = serverSocket.accept();
map.put("someKey", client);
when you have to send message to any specific client. just get his connection from map by giving its key.
Socket clnt = map.get("someKey");
// further processing.
in c# you can use dictionary in place of maps.
You have to keep track of the clients that connect to your server. Most likely using a client ID with a Key/Value collection (try looking up Map).

RMI security and design

I have a server which allows RMI connections. It exposes a "Server" object on the registry for remote calls, which has a method "authenticate". That method, if successful, returns a "user" object. This user object can then be used by the client to get some data.
It looks like this:
RMIServer server = new RMIServer ();
Naming.rebind("rmi://"+ hostName +"/" + AUTH_OBJECT_BINDING, server);
RMIServer then has a method:
public InterfaceUser Authenticate(String username, String password);
This method checks the username/pw and returns a user object (actually the interface). The user object saves some string which contains the username, and a list of permissions. This can then be checked when calling other methods further down the line.
My question is this:
Someone wants to develop a (another) client for the server, to do this I would give them the interfaces required to interact with it (e.g, the InterfaceUser interface, as well as others). I would need to set up a fake "development" server somewhere to allow them to do this, which they can connect to. Is it possible for that developer to use the interfaces to allow it to get an instance of "InterfaceUser" from the real server without correctly authenticating? For example, Bob logs in to the real server, the server creates a User object which implements InteraceUser. Can Alice, with the interfaces, hijack that object or find it somehow on the registry? All other objects are exported on the same port (if this makes a difference).
Or, can Alice authenticate with the fake server, then somehow use that to access the real server? Let's assume that all usernames/passwords are different on the "real server" and the "development server"
Thanks, any help is appreciated.
Alice can't get any user object unless she can login to a server that provides it.
Any user object Alice does get is bound to the server that created it, and can't be used on another server. It doesn't even survive power cycling of the correct server.
Does that answer your question?

How do I communicate with a specific process in one Erlang node?

I have an Erlang server which is spawning a new process for each client that connects. Then the Pid of this new process is passed to the client (to make a connection to the new process.) Is that enough to make a connection from a jinterface client?
I am using this to connect from the client first:
final String SERVERNAME = "server";
final String SERVERNODE = "bertil#computer";
mbox.send(SERVERNAME, SERVERNODE, connectClient);
And those names is set in the server when it starts:
start() ->
net_kernel:start([bertil, shortnames]),
register(server, self()).
Do I have to register a new name for each spawned process? That would not be so dynamic... How do I solve this? Should I use the main process at the server as a router to send all traffic through?
Once you have a pid, you should be able to send a message directly to it. In Erlang you don't have to specify a node if you got a pid. You only need a node if you are sending to a registered name since names are only unique per nod. Pids are unique in the whole cluster.
If you have a varable my_pid as an OtpErlangPid object you can send like so:
mbox.send(my_pid, message);
See the documentation for the send function and chapter 1.6 Sending and Receiving Messages in the Jinterface User's Guide.

connect to a lacewing server chat

I'm trying to make a port of a chat program a friend of mine made with lacewing and multimedia fusion 2 for android device.
I've managed to create a socket connecting to the listening socket of the server successfully, but I cannot seem to be able to send data to login and enter the chat. The login for now just requires a name, but even if I send a String of data, the server doesn't seem to reply or accept that data to get me over the channel.
I know I could easily port this with other way like using the NDK of the multimedia fusion 2 exporter, but I just want to figure out how this works
PS: I'm using Java and libgdx for the development
You need to read the liblacewing relay protocol:
https://github.com/udp/lacewing/blob/0.2.x/relay/current_spec.txt
On initial connection, you have to send byte 0 to identify that you are not an HTTP client. After this, you can exchange normal protocol messages.
The first message you need to send is the connection request (which may be denied by the server with a deny message). This would be:
byte 0 (2.1.0 request)
(1.2 size)
byte 0 (2.1.0.0 connection request)
string "revision 3" (2.1.0.0 connection request -> version)
When the server responds with response 0 (2.2.0.0 Connect), you then have to set a name before you may join any channels. This is done with message 2.1.0.1 SetName, which is the same structure as above but instead of 2.1.0.0's byte 0, it is 2.1.0.1's byte 1, followed by the name as a string instead of the protocol version.
The server should then respond with 2.2.0.1 SetName, assuming it accepted your name change request. You should process this message in case the server gave you a different name than you requested. Finally, once you have a name, you can join a channel with 2.1.0.2 JoinChannel. The flags you specify here will be used if the channel doesn't exist yet (e.g. nobody is in the chat yet) - these should match the ones in the MMF2 project file. The name should also match.
After all that, you're still not done! You have to process more messages, etc. it's almost like writing the RelayClient class yourself. It's a tough task, but with the protocol specification in hand you should be able to work it all out.

Categories