Netty client receives the message delay - java

1.scene description:
Device sen data to Netty Server(about ## 20ms intervals ##), Netty Server forward msg to Client ## Immediately ##(IOS or Android).
2.Associated business code
ctx.writeAndFlush(msg)
protected void doWrite(ChannelOutboundBuffer in) throws Exception {
int writeSpinCount = -1;
boolean setOpWrite = false;
for (;;) {
//Get the data of the first node that needs to be flushed
Object msg = in.current();
if (msg instanceof ByteBuf) {
ByteBuf buf = (ByteBuf) msg;
boolean done = false;
long flushedAmount = 0;
// Get the number of spin lock iterations
if (writeSpinCount == -1) {
writeSpinCount = config().getWriteSpinCount();
}
// Spin, write out the current node
for (int i = writeSpinCount - 1; i >= 0; i --) {
int localFlushedAmount = doWriteBytes(buf);
if (localFlushedAmount == 0) {
setOpWrite = true;
break;
}
flushedAmount += localFlushedAmount;
if (!buf.isReadable()) {
done = true;
break;
}
}
in.progress(flushedAmount);
// After writing, delete the current node
if (done) {
in.remove();
} else {
break;
}
}
}
}
protected int doWriteBytes(ByteBuf buf) throws Exception {
final int expectedWrittenBytes = buf.readableBytes();
return buf.readBytes(javaChannel(), expectedWrittenBytes);
}
3.issue
The netty Server can receive the device data in time
and netty Server can write the data to Socket Buffer in time also.
But The Netty client receives the message delay!!!(eg. 5s delay)
4.Server bandwidth configuration
Inbound 100M/bps bit per seconds.
Outbound 5M/bps bit per seconds.

Client terminal length packer caused by the problem.

Related

Arduino Servo working in setup function but not with bluetooth command

i am experiencing a very strange issue, i wrote code for arduino UNO 3 which is designed to unlock door using servo motor, components attached are following
Servo Motor
1 Red Led (for failure alert)
1 Green Led (for success alert)
1 Buzzer (for audible alert on unlock)
The code is following
#include <Arduino_JSON.h>
#include <SoftwareSerial.h>
#include <EEPROM.h>
#include <Servo.h>
String com = "";
const int buzzer = 6;
const int ledfalse = 8;
const int ledtrue = 13;
const int servo = 11;
Servo myservo;
SoftwareSerial mySerial(2, 3);
void ResetAdmin()
{
for (int i = 0 ; i < EEPROM.length() ; i++)
EEPROM.write(i, 0);
Blink(ledtrue, 2);
}
void WriteAdmin(String admin)
{
byte len = admin.length();
EEPROM.write(0, len);
for (int i = 0; i < len; i++)
{
EEPROM.write(i + 1, admin[i]);
}
Blink(ledtrue, 2);
}
String ReadAdmin()
{
int newStrLen = EEPROM.read(0);
char data[newStrLen + 1];
for (int i = 0; i < newStrLen; i++)
{
data[i] = EEPROM.read(i + 1);
}
data[newStrLen] = '\0';
return String(data);
}
void Unlock()
{
Alert();
myservo.write(0);
delay(500);
myservo.write(90);
delay(6500);
myservo.write(360);
delay(500);
myservo.write(90);
}
void Blink(int type, int times)
{
for(int i = 1; i <= times; i++)
{
digitalWrite(type, HIGH);
delay(80);
digitalWrite(type, LOW);
delay(80);
}
}
void Alert()
{
for(int i = 1; i <= 4; i++)
{
tone(buzzer, 1000);
delay(80);
noTone(buzzer);
delay(80);
}
}
void ProcessCommand(String command)
{
if(command == "unlock")
Unlock(); //not works here
else if(command == "reset")
ResetAdmin();
else
{
Blink(ledfalse, 2);
}
}
void setup()
{
myservo.attach(servo);
mySerial.begin(9600);
pinMode(buzzer, OUTPUT);
pinMode(ledfalse, OUTPUT);
pinMode(ledtrue, OUTPUT);
//Unlock() or Blink(ledtrue, 4) or Alert() works here
digitalWrite(ledtrue, HIGH);
digitalWrite(ledfalse, HIGH);
delay(3000);
digitalWrite(ledtrue, LOW);
digitalWrite(ledfalse, LOW);
}
void loop()
{
while(mySerial.available() > 0)
{
delay(10);
com += (char)Serial.read();
}
if(com.length() > 0)
{
JSONVar doc = JSON.parse(com);
if (JSON.typeof(doc) != "undefined")
{
String admin = ReadAdmin();
if(admin == "")
{
admin = doc["admin"];
WriteAdmin(admin);
}
if(admin == doc["admin"])
{
ProcessCommand((const char*) doc["command"]);
}
else
{
Blink(ledfalse, 2);
}
}
else
{
Blink(ledfalse, 2);
}
com = "";
}
delay(10);
}
The java snippet for sending command is following
private void Unlock() {
if (btSocket != null) {
try {
String payload = "{\"admin\": \"" + getUUID() + "\", \"command\": \"unlock\"}";
btSocket.getOutputStream().write(payload.getBytes());
} catch (Exception e) {
e.printStackTrace();
biometricLoginButton.setImageResource(R.drawable.warning);
failed = true;
Toast.makeText(getBaseContext(), "Error occurred while unlocking", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(getBaseContext(), "Door Lock not connected", Toast.LENGTH_SHORT).show();
biometricLoginButton.setImageResource(R.drawable.warning);
failed = true;
}
}
The issue is when i put the Alert(), Unlock() & Blink() function in the Arduino setup function then alert is working fine and so do the other two, but when the same functions called using Bluetooth signal none of them works. Note that the function is called as servo try to move but not correctly, this shows that Bluetooth is receiving data correctly from android and conditions are being evaluated correctly.
Finally i myself figured out the issue, basically the problem was with the EEPROM of the Arduino the problematic section of the code is following
String admin = ReadAdmin();
if(admin == "")
{
//on first run it never returned empty string, may be my reading function bug
admin = doc["admin"];
WriteAdmin(admin);
}
if(admin == doc["admin"])
{
//due to garbage value compared with actual one this block never executed
rocessCommand((const char*) doc["command"]);
}
else
{
Blink(ledfalse, 2);
}
First condition is for the first run so that when there is no admin stored in the EEPROM, then store the one coming in the JSON, but i don't know why but it was always some garbage value instead of empty or null string that's why the admin was not being matched e.g. the garbage value and the one received in JSON and thus not running the Unlock sequence

Multiple threads reading from ConcurrentLinkedQueue, and entry to DB. Not all entries are being written

I have a method, that writes about 7 million entries to the queues.I'm reading the entries one by one, in multiple threads, and writing it to a DB. Here is the code snippet for the class that does it.
Again, this is executing in a multithreading environment.
private class WriteRunner<T> implements Callable<Long> {
// member variables
public WriteRunner(ConcurrentLinkedQueue<T> elementsQueue,...)
//constructor
}
#Override
public Long call() throws Exception {
while (!elementsQueue.isEmpty()) {
int failures = 0;
T t = elementsQueue.poll();
while (true) {
try {
// write to DB
break;
} catch (Exception e) {
//Log error
//Wait for 10 seconds and retry
Thread.sleep(10000);
if (++failures > 10) {
throw new Exception(
String.format("[TID: %d] Connection repeatedly failed.", threadId));
}
}
}
}
//log more stuff
return (long)total;
}
}
Here is how I'm calling the method
for (int i = 0; i < N_THREADS; i++) {
completionService.submit(
new WriteRunner<T>(elementsQueue ,...));
}
long total = 0;
for (int i = 0; i < N_THREADS; i++) {
total += completionService.take().get();
}
I'm missing as many entries, as there is the number of exceptions.
My idea is to, retry on the same 't' element that's the latest poll.
What is going wrong with the exceptions?

bulkTransfer returns positive value but communication is not successful

As stated by Google at Android Developers
public int bulkTransfer (UsbEndpoint endpoint, byte[] buffer, int
length, int timeout)
Returns length of data transferred (or zero) for success, or negative value for failure
Well, after performing a bulkTransfer in my app for a USB CDC communication
// send data to usb device
byte[] bytes = data.getBytes();
sentBytes = connection.bulkTransfer(output, bytes, bytes.length, 1000);
sentBytes is receiving the value of 16, which is great, because I'm sending 16 bytes indeed.
It should indicate that the bytes were sent correctly. :-)
However, they're NOT. I can't see any results on the other side.
After doing a rearch I found out that it could be an Interface problem, so here it's how I'm getting it from the device:
private void setupConnection()
{
// find the right interface
for(int i = 0; i < usbDevice.getInterfaceCount(); i++)
{
// communications device class (CDC) type device
if(usbDevice.getInterface(i).getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA)
{
intf = usbDevice.getInterface(i);
// find the endpoints
for(int j = 0; j < intf.getEndpointCount(); j++)
{
if(intf.getEndpoint(j).getDirection() == UsbConstants.USB_DIR_OUT && intf.getEndpoint(j).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)
{
// from android to device
output = intf.getEndpoint(j);
}
if(intf.getEndpoint(j).getDirection() == UsbConstants.USB_DIR_IN && intf.getEndpoint(j).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)
{
// from device to android
input = intf.getEndpoint(j);
}
}
}
}
}
What could I be possibly missing?

Sending numbers via Serialport from C# to Java

I'm making a Bluetooth quadcoopter using Arduino. I have no problem sending letters, but I cant seem to write or read numbers.
I'm not very good at programing so bear with me.
C# code:
private void button1_Click(object sender, EventArgs e)
{
int testInt = 35;
byte[] testByte = BitConverter.GetBytes(testInt);
serialPort1.Write(testByte, 0, 0);
int i = BitConverter.ToInt32(testByte,0);
label5.Text = i.ToString();
}
Here I've tried to convert to send a byte, at first I just sent it directly as a string. I get the same result from both ways.
Arduino code:
<code>void loop()
{
// put your main code here, to run repeatedly:
if(Serial.available())
{
int data = Serial.read();
if(data=='35')
{
digitalWrite(13, HIGH);
}
}
}
Why don't the LEDs light up? How do I read numbers from a serial port?
This sends a single byte (0 to 255):
private void button1_Click(object sender, EventArgs e) {
// set up to send only one byte
byte[] testByte = {35};
// send one byte
serialPort1.Write(testByte, 0, 1);
}
And this receives and interprets it on the Arduino:
void loop() {
if (Serial.available()) {
byte data = Serial.read();
if (data == 35) {
digitalWrite(13, HIGH);
}
}
}
If you think you might send a number greater than 255, it's probably just as easy to send a string. Add a new line character to the end of the string:
String testString = "35\n";
and use the new line to let the Arduino know you're done sending the code, something like this:
#define MAX_SIZE 5;
char button[MAX_SIZE+1];
if (Serial.available()) {
int bytesRead = Serial.readBytesUntil ('\n', button, MAX_SIZE);
if (bytesRead > 0) {
button[bytesRead] = '\0';
int result = atoi(button);
if (result == 35) {
digitalWrite(13, HIGH);
} else {
digitalWrite(13, LOW);
}
}
}

What is "Sim blocking" (seen in tomcat doc)?

I saw the following description in the official tomcat configuration documentation (APR connector description omitted):
Java Blocking Connector Java Nio Blocking Connector
Classname Http11Protocol Http11NioProtocol
Tomcat Version 3.x 4.x 5.x 6.x 6.x
Support Polling NO YES
Polling Size N/A Unlimited - Restricted by mem
Read HTTP Request Blocking Non Blocking
Read HTTP Body Blocking Sim Blocking
Write HTTP Response Blocking Sim Blocking
SSL Support Java SSL Java SSL
SSL Handshake Blocking Non blocking
Max Connections maxThreads See polling size
What does "Sim Blocking" mean?
According to Filip Hanik, a Tomcat committer, it means "simulated blocking". (Reference: Tomcat User Mailing list post)
Just a guess, but it could stand for simulated blocking, meaning a blocking api wrapped around the underlying non-blocking nio api.
SourceCode: https://github.com/apache/tomcat/blob/8.5.x/java/org/apache/tomcat/util/net/NioEndpoint.java
/**
* NioEndpoint.NioSocketWrapper.fillReadBuffer() 用于直接读取内容到 传入的任意 ByteBuffer 中
*
* #param block 是否阻塞读
* #param buffer 待接收数据的buffer
* #return 读取到的字节数
* #throws IOException
*/
private int fillReadBuffer(boolean block, ByteBuffer buffer) throws IOException {
int n = 0;
if (getSocket() == NioChannel.CLOSED_NIO_CHANNEL) {
throw new ClosedChannelException();
}
if (block) { // if no readListener. block variable is true.
long timeout = getReadTimeout();
long startNanos = 0;
do {
if (startNanos > 0) {
long elapsedMillis = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanos);
if (elapsedMillis == 0) {
elapsedMillis = 1;
}
timeout -= elapsedMillis;
if (timeout <= 0) {
throw new SocketTimeoutException();
}
}
n = getSocket().read(buffer);
if (n == -1) {
throw new EOFException();
} else if (n == 0) {
if (!readBlocking) {
readBlocking = true;
registerReadInterest(); // <=============== (向关联的Poller)注册读事件.
}
synchronized (readLock) {
if (readBlocking) {
try {
if (timeout > 0) {
startNanos = System.nanoTime();
readLock.wait(timeout); // block itself here < ===================
} else {
readLock.wait();
}
} catch (InterruptedException e) {
// Continue
}
}
}
}
} while (n == 0); // TLS needs to loop as reading zero application bytes is possible
} else {
n = getSocket().read(buffer);
if (n == -1) {
throw new EOFException();
}
}
return n;
}

Categories

Resources