I want to build a client-server-application for some practice. I started off with a simple chat which was not so hard to do. I'm also able to identify different commands by just simply split a String, e.g. "command:msg". But I think that may be a little inconvenient. So I'm wondering if there are better ways to realize that. And I stumbled over that side:
http://www.javaworld.com/jw-01-1997/jw-01-chat.html?page=6
At the very end it says:
An alternative, however, and much more elegant solution, is to abstract the protocol behind a set of stream classes. The specifics of header construction and insertion can be handled automatically by the stream classes, and the client is then left with much the same interface as before: Clients write messages to a stream, but instead of flushing the stream, they call a method that attaches appropriate headers and sends the encapsulated message.
I don't really know what is meant by that. Could somebody explain it, or even better, give me a code example. Perhaps there may are other ways to do?
Let's say you want to send messages encapsulated as the link you sent:
| ID | len | message contents |.
What they mean with "to abstract the protocol behind a set of stream classes" is to create classes that extend stream classes which will put the correct ID and length on the encapsulated message for you.
For example, for an extended PrintWriter where you send two kinds of message:
ID 1 - normal message.
ID 2 - error message.
class MyProtocolPrintWriter extends PrintWriter {
public static final int NORMAL_MESSAGE = 1;
public static final int ERROR_MESSAGE = 2;
//put the constructor
public void writeMessage(String message) {
println(
String.format(
"%02x%02d%s", NORMAL_MESSAGE, message.length(), message));
}
public void writeErrorMessage(String message) {
println(
String.format(
"%02x%02d%s", ERROR_MESSAGE, message.length(), message));
}
}
Here's what one fairly successful chat network used for a protocol.
Internet Relay Chat
And here's a list of the commands that were implemented using the IRC protocol.
List of Internet Relay Chat commands
You would implement these commands as a set of stream classes. The user issues a command, and your stream class handles the specifics of the header construction and insertion into the stream.
Related
I have a servicebusqueuetrigger function that takes a string off the service bus and calls another api, if that api call does not return a 200, I want to move that string as a meesage into a dead letter queue. How can I do this?
So far I have this...
public class myEventsConsumerFunction {
#FunctionName("myEventTrigger")
public void myEventTrigger(
#ServiceBusQueueTrigger(name = "message", queueName = "%QUEUE_NAME%", connection = "ServiceBusConnection") String message,
final ExecutionContext context) throws MSPException {
int responseCode = callApi(message);
if(responseCode!=200){
String ConnectionString = "connectionstring"
QueueClient sendClient = new QueueClient(new ConnectionStringBuilder(ConnectionString, queueName), ReceiveMode.PEEKLOCK);
//
//how do i send my String message to dead letter queue here?
//
}
I see a bunch of methods in queue client called deadletter, but they take a UUID as a parameter (I am not sure what that is), and not a message String.
The key to the problem is that the Java-based azure sdk package of offcial didn't not write the MessageReceiver class. (As far as I know, the official only implements the IMessageReceiver interface of C#) If it is C#, you can use it directly:
https://learn.microsoft.com/en-us/dotnet/api/microsoft.azure.servicebus.core.messagereceiver?view=azure-dotnet
But for java, The official has not yet implemented this, only a interface:
https://learn.microsoft.com/en-us/java/api/com.microsoft.azure.servicebus.imessagereceiver?view=azure-java-stable
I see a bunch of methods in queue client called deadletter, but they
take a UUID as a parameter (I am not sure what that is), and not a
message String.
I know this, but it is not based on messages, if you create an object of queueclient and use the method, it will tells you no receiver:
In summary, I think this is an unfinished feature, and maybe it can be updated in a future sdk version. But not now, unless you read the underlying code and implement the IMessageReceiver interface yourself, otherwise it will be impossible.
I encountered the same issue, the github issue is still open.
Help me please with the question:
I need to get information about the queue (the best option would be for a particular queue and all queues). I use the asterisk-Java 2.0.3 library. For information about a particular queue, I can send the action - QueueSummaryAction. To get all the queues I can use the AsteriskServer object and get the information using getQueues(). However, this information is slightly incomplete.
In addition, I connect to the server Asterisk via telnet. And after doing the appropriate action (action: queues), I get a list of queues with pretty good information (see image).
I would like to somehow get this with the help of AMI and the implementation presented in this library. Can there be any analogy? For example, I'm interested in the number of calls, the number of responses, deductions (in image it's W:0, C:5, A:24, SL:100.0%, within 60s). But, unfortunately, I did not find a way to get such information. Part of the presented in the image, I can get, but I would like more (regarding the queue itself, not the queue members).
About my implementation.
I create a new DefaultAsteriskServer. Next, I add my listeners (I will not describe them here).
public void build(String hostname, int port, String username, String password)
{
asteriskServer = new DefaultAsteriskServer(hostname, port, username, password);
asteriskServer.initialize();
LOGGER.info("Asterisk server initialized");
}
public void addEventListener(ManagerEventListener eventListener)
{
asteriskServer.getManagerConnection().addEventListener(eventListener);
}
Actually, that's all.
Thank you all in advance for your help.
You should issue manager action "COMMAND"
In parameters you can put same request you show on your screen
I need to implement a heartbeat system on my Java project (3-5 Clients with 1 server for them) but I have some questions.
1) Do I need to have 2 sockets by clients ? 1 for the heartbeat and 1 to receive normal message for my software
2) I saw that in specific case when a client is lagging, the client don't receive a message, how to avoid this ?
3) In case of a client disconnect, how to retreive the connection with it ? Without recreate a new socket with it.
So, you have a "central server" which needs to provide an heartbeat mechanism to the clients. Well, part of the solution is simple since you have only 1 server, which simplifies a LOT since you don't need to deal with data replication, data synchronization mechanisms, server failure, and so on. You just expect that your server never fails and if it fails it's a fatal error.
My suggestion is to implement a system based on notifications (pooling is bad and ugly): instead of having the server pooling the clients, you have the clients reporting to the server every X seconds of their state. This reduces the general overload of your system and it's based on the design principle of "Tell, don't ask". This also allows you to have different report times for each individual client.
There is one more question, which is what data do you want to transmit? Simply if the client is alive? Runtime data of the client, for example, % of it's job done if the client is downloading a file? Environment status, such as CPU overload, memory usage, network status? Define that, that's the first step.
Talking about the java implementation, you should run your a thread on each of your clients (implementing the Runnable interface). It should look something like this code (this is simplified for the sake of brevity):
public class HeartbeatAgent implements Runnable {
private int DEFAULT_SAMPLING_PERIOD = 5; //seconds
private String DEFAULT_NAME = "HeartbeatAgent";
private HashMap<Integer, Object> values; // <id, value>
public HeartbeatAgent () {
values = new HashMap<Integer,Object>();
}
private void collect() {
/** Here you should collect the data you want to send
and store it in the hash
**/
}
public void sendData(){
/** Here you should send the data to the server. Use REST/SOAP/multicast messages, whatever you want/need/are forced to **/
}
public void run() {
System.out.println("Running " + DEFAULT_NAME );
try {
while( /** condition you want to stop **/ {
System.out.println("Thread: " + DEFAULT_NAME + ", " + "I'm alive");
this.collect();
this.send();
// Let the thread sleep for a while.
Thread.sleep(DEFAULT_SAMPLING_PERIOD * 1000);
}
} catch (InterruptedException e) {
System.out.println("Thread " + DEFAULT_NAME + " interrupted.");
}
System.out.println("Thread " + DEFAULT_NAME + " exiting.");
}
}
You should write a server that handles the requests made and is "smart" enough to call a time-out after X seconds without "news" from client Y.
This is still not ideal, since you collect data and send it with the same sampling period, but usually you want to collect data at very tiny intervals (collecting CPU usage every 5 seconds, for instance) but only report it every 30 seconds.
If you want to look at good code of a good library that does this (it's what we've been using to our project at my company), take a look at JCatascopia framework code (just look at the Agent and Server folders, ignore the others).
There's a lot to say about this topic, this is the basic. Feel free to ask!
You could try to take a look at this small framework I made for a project I'd worked one last year. It's focused on a simple implementation and yet a strong feedback about your clients status.
It's based on UDP protocol which sends a payload containg an id, which it can be a MAC address of a NIC or an id chosen and set automatically by you or something else too, that confirms the client being safe and sound.
I think it's kind of cool because it's based on listeners which then receive various kinds of events based on what the heartbeat protocol compute about a client status.
You can find more about it here
I think it's handy to use it with TCP sockets to understand if you are capable or not to send data over your TCP stream. Having continuos feedback on your clients status takes you in a position where you can easily achieve that, for example by saving in some sort of map your client status and check it before sending any kind of data.
using this code:
Java Server side:
...
out = new PrintWriter(this.client.getOutputStream(), true);
...
public void sendMsg(String msg) {
out.println(msg);
//out.flush(); // we don't flush manually because there is auto flush true
}
C# Client side:
while(connected) {
int lData = myStream.Read(myBuffer, 0, client.ReceiveBufferSize);
String myString = Encoding.UTF8.GetString(myBuffer);
myString = myString.Substring(0, lData);
myString = myString.Substring(0, myString.Length-2);
addToQueue(myString);
}
variable myString have many messages that server should send them one by one like
hello \r\t hello \r\t ...
they should come separately like
hello \r\t
hello \r\t ...
which means when i wait one by one they come instantly all of them in a row, how can i make it to send one by one in separate flush.
Note I send 30~ messages in a row in one second (1s), i want them separate.
TCP supports a stream of bytes. This means you have no control how the data arrives regardless of how you send it. (Other than it will comes as bytes) You should rethink your protocol if you depend on it coming in any particular manner.
You can reduce the amount of bunching of data but all this does is reduce latency at the cost of throughput and should never be relied upon. This can be reduce (but not eliminated) by turning off Nagle and reducing co-alessing setting in your TCP driver if you can change these.
i want them separate.
You can want it but TCP does not support messages as you would want them.
The solution in you case is for your reader to match your writers protocol. You send lines so you should read lines at a time, e.g. BufferedReader.readLine(), not blocks of whatever data happens to be in the buffer.
The application that I am working on has two parts. The server part runs on a Linux machine. The client part, an Android application, queries the server and gets necessary response. Both the parts are written in Java, use socket-based communication, and transfer textual data.
Right after sending the request, here is how the client receives the response:
public static String ReadAvailableTextFromSocket(BufferedReader input) throws IOException {
if (input.ready() == false) {
return null;
}
StringBuilder retVal = new StringBuilder();
while(input.ready()) {
char ch = (char) input.read();
retVal.append(ch);
}
return retVal.toString();
}
However, this doesn't seem to be that reliable. The input is not always ready because of server response time or transmission delays.
Looks like input.ready() is not the right way to wait for getting data.
I am wondering if there is a better way to accomplish this. Perhaps there is some standard practice that I could use.
Perhaps you should use Threads. Keep a listener thread in a while(true) loop that reads more data as it comes in, and simply buffers the data in a data structure (let's say a queue) shared with the main thread. That way, the main thread could simply dequeue data as needed. If the queue is empty, it can infer that no new data was received.
Edit: see this multithreaded chat server/client code as an example.
Here is how I solved this problem. As I am responsible for writing both, the client side as well as the server side, when a request comes to the server, the first line of information I send as the response is the number of bytes the client can expect. This way, the client first waits to read a line. Once the line is read, the client now knows how many bytes of data to expect from the server.
Hope this helps others.
Regards,Peter