So I've tried to send players to the lobby server when they type "/lobby" by using this code:
Bukkit.getServer().dispatchCommand((Player) player, "server lobby");
But in game, it returns "Unknown Command. Type "/help" for help."
I've also read to try this code, but I don't know what to put in place of "a", "b", and "c"
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("a");
out.writeUTF("b");
//applies to the player you send it to. aka Kick To Server.
Player player = Bukkit.getPlayerExact("c");
player.sendPluginMessage(this, "BungeeCord", out.toByteArray());
So my question is why does the first method not work? Also, how do you make the second solution work? Is there code I need to put in the bungee server?
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("Connect");
out.writeUTF("ServerName");
player.sendPluginMessage(PluginObject, "BungeeCord", out.toByteArray());
This is what you are looking for. To answer your question, "a" is always "Connect". "b" is the name of the server that you want to connect to (In your case this is "lobby"), and "c" will the name of the player (This is because in the example that you've supplied your getting the player by their name, however if you've already got the player object, this isn't needed).
And just so that you understand why dispatchCommand doesn't work, it's because when you do /server on your client it sends a packet to the Bungeecord as that's what your client is connected to, and it will intercept that command packet read it and see that it's a server command. It will then proceed to connect you to the right server. If you use dispatchCommand on the Bukkit server it will execute the command as though it just received an command packet, which means it never sends out any sort of message to the bungeecord or to the client to get it to execute a command. The dispatchCommand method will only be run on the bukkit server.
The reason that the second solution works is because in the Minecraft protocol there's this thing called the plugin messaging channel, for custom messages between the client and the server. And yet again as the Bungeecord sits in the middle of the client and the server, it listens on certain messages, and any of them tagged with Connect will connect a player to the specified server. I hope this makes sense.
Related
Take it easy with me, I'm new in socket programming.
I'm about making a program which is similar to Teamviewer. I could make a simple Server/client application which is multithreaded. But the problem is I couldn't figure out how to do something like :
Let's say I have Server and a client connected to server.
I could transfer a file from client to server. I could make a simple chat with a client. But my problem is : How can I chat with the client while file is transferring in the same time? I mean I couldn't make more than one function in a time.Because we have just one input and one output for both server and client. So how could I send more that one function to client and how could the client read more that one function in a time and respond to requests ?
I did something like : I sent a request to client and I got the response in a new thread which contains a new DataInputStream but I couldn't figure out how the main DataInputStream will receive a new response from the client because what is receiving the requests in this way is the new DataInputStream. I'm really lost in this situation because I feel my concept is completely wrong but I couldn't figure out the right concept to do something like that.
Is it possible with ServerSocket or should I look at NIO Socket ?
NOTE :
I don't want a piece of code, I would like to understand the concept of the whole operation for something like that. Thank you
Use a packet based massaging system over a single connection
Outgoing
{"type":"chat", "message":"hi"}
{"type":"xfer", "fileName":"fileX", "data":"some_binary_data"}
Incoming
switch(getString("type")){
case "chat":
System.out.println("User said" + getString("message"));
break;
case "xfer":
File f = new File(getString("fileName"));
f.write(getString("data"));
break;
...
}
Obviously if the binary file is fairly large, you should break it into many different messages and reassemble it on the other side, this would allow chat messages to make their way across the wire while the transfer is also still taking place.
Kindly find in the details of assignment:
Start a TCP Server.
Start multiple clients to connect to the server.
On connect :
Server gives each connection a random unique name
Server starts sending PING messages to client as : “PING client abc123 at time hhmmss” every 5 seconds.
Client receives the PING messages and prints them to console.
On connect :
Client starts sending “Time request” messages every 10 seconds
Server gets the message and responds : “Client abc123, the time is hhmmss”
Client gets the time messages and prints them to console.
Things to note :
Use plain sockets (not NIO)
Make sure that the socket handling code is reusable
Make sure that the time request reads and writes are asynchronous.
Ensure that ping and all other reads and writes are also asynchronous
Ensure that ping and time response messages do not intersperse or corrupt each other
We are not here to write a program for you, but here is some stuff you can use to solve most of the problems in your project.
First off you are using TCP in Java so you will be using the following objects:
Socket - Client connection
ServerSocket - Server host
There is documentation on how to use these here.
Server side, you want multiple connections and you will want the rest of the program to run. This means multitasking. The ServerSocket should run on a separate thread. Then it should be put in a do-while loop to accept() connections. The server will then wait there until a client socket connects. When a connection is made you will need to create a new thread to let the ServerSocket accept more clients. Make sure when multi threading to use synchronized methods.
Create ServerSocket like this: new ServerSocket(port); This will open server on int port.
On the client side we will also use multithreading. The Socket will need to be on a seprate thread and to create a Socket to connect to an ip and port do the following: new Socket(ip, port) (ip is a String)
Once connected both the server and client will need to communicate. An easy way to do this is to send a message back and forth. You can't just not send because the server or client will pause and wait on receive and not be able to send. I will get to this issue in a minute.
One way to send would be to use a PrintWriter. Create a new PrintWriter with the Socket output stream. From here you can send by printing line with PrintWriter.
Make sure you flush or autoFlush your PrintWriter or else it will keep sending the same message over and over.
You can then receive a message by using BufferedReader by creating a new InputStreamReader from the socket input stream. Doing this you can use readLine(). Remember this will pause until something is received.
Doing this on both the server and client you can send back and forth. Once at this point you could easily do the rest of your requested assignment.
As I mentioned earlier, this method will result in the server and clients sending and receiving over and over even if the message is empty. Doing the following can prevent this and use less cpu and bandwidth as it will only send when it has a message to send:
(I created this diagram for a forum post for a project update I have created once)
The green lines represent received data going somewhere and the red represent data from the program going to the sender thread to be sent.
Notice on this diagram that there is a thread for receiving and sending. This allows one to send messages while the other receives, so the sender won't pause if the receiver does pause to wait to receive a message.
Other good resources:
Simple Chat Program
enter link description here
I am one server and multiple clients via threads. The client(s) send their message to the server. I have worked out how to make the server send the message back to client like a echo system. If I have two clients, I want them to send their message to the server and the server should send it to the client that did not send the message i.e. the other client. How would I go about send the message back to all the clients apart from the one that send the message?
When the message comes in, determine what the userID / other identifying id the incoming message is associated with. Then re-broadcast to all other sockets, but exclude the Socket associated with the ID that sent the message
Make at the server side a list with all the clients...
every time a new msg is received, then iterate the list and send the msg using the port of the socket as id...
I recently wrote a Chat program too. What I did was, I had a class ClientHandler that handles the connection for each individual client.
Inside ClientHandler I had a HashMap. I added each client that had connected to the HashMap, with the Key being the client id. I used a UUID rather than int for the client id.
Inside this handler class, I had a sendMessage(String str) method. Within this method, a for-each loop that loops through each ClientHandler object, checking the values inside the HashMap. Inside this for-each loop, I have an if statement that checks whether you are writing to the ClientHandler object with this id. If the check returns false, you go ahead and write the message on the PrintWriter and the message won't be sent to the client writing the message.
This worked for me. Might not work for you.
How I can send file from one client (A) to another one (B) via socket? and vice versa, send file from B to A. I mean that make the client sender and receiver at the same time.
In other word, when muticlient connect to server, how I distinguish between clients ?
You need to implement you own communication message format in short a simple protocol .
You keep a list of all active sockets in a shared list/map , and based on the request from the message you pick up the apt client and push the desired message to that.
You can implement the actual message format as you want, but this can be the blueprint.
In this case lets say your client A sends message : 1. Client Id 2. File Start 3 X . File Content 4. File End
as soon as you get a connection you get the target client id , the file start message lets you understand the next message just needs to be diverted to target and file End message defines the transfer complete.
Also, you may would like to send Acknowledgement message from server to client, in order to eradicate transfer issues.
It is good way to manage client using their id(i.e. a unique long or string or any other for each user). At the time of connection to socket client send their id , store that is in collection. And when a user(Client) want to send file send with own id and Id of that user(Client) want to send.
I am trying to implement a simple chat application that connects clients through a central server, with other client so they can exchange messages and files. I also need to implement a notification framework. for example, if a user signs successfully, or if a buddy of him signs in he get a notification.
Now in the RMI world how is this implemented?
I was thinking of having a remote object "connection class" that the clients call methods from it like "login in", "disconnect" etc...
And as for the notification framework classes do they have to be remote too? or can they lie in the server?
thanks
Event messaging between remote systems is a bit tricky. Here's what has to happen:
The client must register interest in the events fired on the server side. To register, the client must be remotely available to the event source object.
In order to be able the register, the client must find the server to begin with, so the server object must be remotely available to the client.
Ick, right? And that's the simple pattern for implementing remote event handling.
A few weeks ago I started a tutorial that was heade down this path -- it's right here, and I'm hoping to add something to it before the end of the week. Alas, the need to make the rent has interfered and I'm not able to add to it as quickly as I'd like.
If you can't wait, however, that's the key: both sides have to be remotely available for the messaging system to work.
that server as well as the client must be remote objects.
Let all clients implement a Remote interface.
RemoteClientIfc extends Remote {
void inform();
}
//have a remote method register() on the *Server* object which accepts RemoteClientIfc.
//c'd be something like this...
register(RemoteClientIfc client){
arrayListofClients.add(client);
}
//So client will do a look up on the remote server object and register itself.
remoteObj.register(clientInstance);
//In the remote server you
//can probably have another method to send notifications to the client.
//Run through the ArrayList and call
//inform() on each of them.
//Thus the client will receive notification.
tellClients(){
Iterator i = ....
while (i.hasNext()){
((RemoteClientIfc).i.next()).inform();
}
}