How to send/read java ByteBuffer (websocket) from javascript client onmessage function - javascript

Server code in java:
#OnMessage
public void onMessage(Session session, ByteBuffer message) {
if (session.isOpen()) {
String msg = new String(message.array());
System.out.println("Message from " + session.getId() + ": " + msg);
try {
session.getBasicRemote().sendBinary(ByteBuffer.wrap("I have got the message".getBytes()));
} catch (IOException ioe) {
System.out.println(ioe.toString());
}
} else {
System.out.println("Session is not open");
}
}
Client code in Javascript:
webSocket = new WebSocket("ws://192.168.10.1:2525/myChat/chat");
webSocket.binaryType = 'arraybuffer';
webSocket.onopen = function(event) {
updateOutput("Connected!");
connectBtn.disabled = true;
sendBtn.disabled = false;
};
webSocket.onmessage = function(event) {
updateOutput(event.data);
};
Note:
Server code works fine when I use it with Web GL client as it is send Binary data.
Javascript client works fine when I read String data in Server end
(from java code):
#OnMessage
public void onMessage(Session session, String message) {}
Thanks in advice for any comments.

I've found the solution to the issue.
I have used ByteBuffer.js library to send/read data of ByteBuffer type in JavaScript:
webSocket.binaryType = "arraybuffer";
In the function onmessage for reading data:
var d = event.data;
console.log(d.toString());
In the function send for sending data:
var bb = dcodeIO.ByteBuffer.wrap(text);
webSocket.send(bb.toArrayBiffer());

Related

How do I parse an image sent from Retrofit API from Android (multipart/form) in Python's Flask

I am sending my image as a part of Form Data through Retrofit API. There are no issues loading the image. I am trying to get this image in a Python Flask server.
My python code is not responding the expected way. I have tested my Python code with a JavaScript frontend application and the python server responds as expected. I believe the issue is parsing the multipart/form file which I receive from Android.
There are no network issues, I am able to log the requests. The detectFace() function is not responding as expected for the same image sent through both clients, VueJs and Android.
Any ideas will be appreciated.
Here is the android code for uploading:
private void sendImageToServer() {
File imageFile = loadImageFromStorage(tempImagePath);
RequestBody reqBody = RequestBody.create(MediaType.parse("image/jpeg"), imageFile);
MultipartBody.Part partImage = MultipartBody.Part.createFormData("file", "testImage", reqBody);
API api = RetrofitClient.getInstance().getAPI();
Call<TestResult> upload = api.uploadImage(partImage);
upload.enqueue(new Callback<TestResult>() {
#Override
public void onResponse(Call<TestResult> call, Response<TestResult> response) {
if(response.isSuccessful()) {
TestResult res = response.body();
String jsonRes = new Gson().toJson(response.body());
String result = res.getResult();
Log.v("REST22", result);
}
}
#Override
public void onFailure(Call<TestResult> call, Throwable t) {
Log.v("REST22", t.toString());
Toast.makeText(MainActivity.this, t.toString(), Toast.LENGTH_SHORT).show();
}
});
}
Here is Python code:
#app.route('/detectFaces/', methods=['POST'])
def detectFaces():
img = request.files.get('file')
print('LOG', request.files)
groupName = 'random-group-03'
result = face.detectFaces(img, groupName)
print('RESULT', result)
return {'result' : result[0]}
VueJs - alternate working frontend (REST client):
sendImage(img) {
console.log(img)
var form = new FormData();
form.append('file', img, 'testImage')
axios.post(this.baseUrl + 'detectFaces/?groupName=random-group-03', form)
.then(res => {console.log(res.data); this.log = 'Detected face ids: \n ' + res.data.result});
}

nodejs not sending websocket to browser

i made a program that connects my java programm who sends data to my nodejs server using sockets and the nodejs server is supposed to send the received data to the browser using socket.io but there is a problem i do receive the data from java but the node server doesnt send it to the browser here is the code
// Create an instance of the Server and waits for a connexion
net.createServer(function(sock) {
// Receives a connection - a socket object is associated to the connection automatically
console.log('CONNECTED: ' + sock.remoteAddress + ':' + sock.remotePort);
// Add a 'data' - "event handler" in this socket instance
sock.on('data', function(data) {
//data was received in the socket and converting it into string
var textChunk = data.toString('utf8');
io.emit('message', textChunk); //socket.io is supposed to send the data to the browser
console.log(textChunk);
});
// Add a 'close' - "event handler" in this socket instance
sock.on('close', function(data) {
// closed connection
console.log('CLOSED: ' + sock.remoteAddress + ' ' + sock.remotePort);
});
}).listen(PORT, HOST);
You may connect Java side (WebSocketServer) to Javascript side (browser) using github.com/TooTallNate/Java-WebSocket.
Java side:
final class Gateway extends WebSocketServer {
private WebSocket _webSocket;
Gateway( IDataManager dataManager, IConfiguration config) {
super( new InetSocketAddress( <host>, <port> );
new Thread( this ).start();
}
#Override
public void onOpen( WebSocket conn, ClientHandshake handshake ) {
final String request = handshake.getResourceDescriptor();
final String[] req = request.split( "[/=]" );
System.out.printf( "request: %s\n", Arrays.toString( req ));
_webSocket = conn;
...
}
public void publish( ... ) {
final ByteBuffer buffer = ByteBuffer.allocate( ... );
buffer.order( ByteOrder.BIG_ENDIAN );
buffer.putXXX( ... );
buffer.flip();
_webSocket.send( buffer );
}
#Override
public void onMessage( WebSocket conn, String buffer ) {
System.out.printf( "%s\n", buffer );
}
#Override
public void onMessage( WebSocket conn, ByteBuffer buffer ) {
try {
System.out.printf( "%d bytes received from %s",
buffer.remaining(), conn.getRemoteSocketAddress());
if( buffer.position() == buffer.limit()) {
buffer.flip();
}
buffer.order( ByteOrder.BIG_ENDIAN );
final byte xxx = buffer.getXxx();
...
}
catch( final Throwable t ) {
t.printStackTrace();
}
}
#Override
public void onError( WebSocket conn, Exception ex ) {
ex.printStackTrace();
}
#Override
public void onClose( WebSocket conn, int code, String reason, boolean remote ) {
System.out.printf( "code: %d, reason: %s, remote: %s\n", code, reason, remote ? "true" : "false" );
}
}
Javascript side:
var webSocket = new WebSocket(
'ws://' + smoc.PROTOCOL_HOST +
':' + smoc.PROTOCOL_PORT +
'/viewID=' + $scope.viewID );
$scope.webSocket.binaryType = "arraybuffer";
$scope.webSocket.onmessage = function( evt ) {
...
};

unable to connect websocket(wss) from c#

In my application I am connecting chrome extension with windows application using websocket,
Javascript code :
var socket = new WebSocket('ws://172.xx.xxx.xx:11223/');
socket.onopen = function(event)
{
// Web Socket is connected, send data using send()
socket.send("hi..");
};
And C# code :
public static TcpListener Weblistener = null;
public static int selWebSocketPort = 0;
public static void StartListeningSahi()
{
Weblistener = new TcpListener(IPAddress.Parse(ipAddStr), portNumForSelenium);
try{
Weblistener.Start();
int TestingCycle = 100;
// Start listening for connections.
while (TestingCycle > 0){
TcpClient handler = Weblistener.AcceptTcpClient();
// An incoming connection needs to be processed.
lock (ClientSockets.SyncRoot){
if (handler != null){
int i = ClientSockets.Add(new ClientHandler(handler));
((ClientHandler)ClientSockets[i]).Start();
SelWebSocketPort = (handler.Client.RemoteEndPoint as IPEndPoint).Port;
NetworkStream networkStream = handler.GetStream();
Byte[] clientReq = new Byte[handler.Available];
networkStream.Read(clientReq, 0, clientReq.Length);
string headerRequest = Encoding.UTF8.GetString(clientReq);
SendResponseToWebSocket(handler, networkStream, headerRequest);
}
else
continue;
}
}
Weblistener.Stop();
}
catch (Exception e){
Console.WriteLine(e.ToString());
}
}
public static void SendResponseToWebSocket(TcpClient handler, NetworkStream networkStream, string headerRequest)
{
// generate accept key fromm client header request
var key = headerRequest.Replace("ey:", "`")
.Split('`')[1]
.Replace("\r", "").Split('\n')[0]
.Trim();
var responseKey = AcceptKey(ref key);
//create the response for the webclient
var newLine = "\r\n";
var response = "HTTP/1.1 101 Switching Protocols" + newLine
+ "Upgrade: websocket" + newLine
+ "Connection: Upgrade" + newLine
+ "Sec-WebSocket-Accept: " + responseKey + newLine + newLine;
//send respose to the webclient
Byte[] sendBytes = Encoding.ASCII.GetBytes(response);
networkStream.Write(sendBytes, 0, sendBytes.Length);
networkStream.Flush();
selWebSocketPort = (handler.Client.RemoteEndPoint as IPEndPoint).Port;
}
This is working fine for http site. But after that I changed the this javascript line var socket = new WebSocket('ws://172.xx.xxx.xx:11223/'); to var socket = new WebSocket('wss://172.xx.xxx.xx:11223/'); to support https sites, but unable to do so. I am getting below error on chrome -
WebSocket connection to 'wss://172.16.106.22:11223/' failed: WebSocket opening handshake timed out
The handshaking is getting failed as in the request header I am getting some junk value.
Am I missing something ?

Why is this node.js tcp server not writing back to Java client until it closes?

Here is an example of a tcp server written in node.js I found:
net.createServer(function(sock) {
// We have a connection - a socket object is assigned to the connection automatically
console.log('CONNECTED: ' + sock.remoteAddress +':'+ sock.remotePort);
// Add a 'data' event handler to this instance of socket
sock.on('data', function(data) {
console.log('DATA ' + sock.remoteAddress + ': ' + data);
// Write the data back to the socket, the client will receive it as data from the server
sock.write('You said "' + data + '"');
});
// Add a 'close' event handler to this instance of socket
sock.on('close', function(data) {
console.log('CLOSED: ' + sock.remoteAddress +' '+ sock.remotePort);
});
}).listen(PORT, HOST);
console.log('Server listening on ' + HOST +':'+ PORT);
I am trying to use this as a basis for a tcp server which will have to handle multiple incoming connections at the same time. Here is a Java program I wrote to test this:
public static final String MESSAGE = "Hellow world";
public static Semaphore networkLock;
public static void main(String[] args)
{
//writeMessage(MESSAGE);
Thread[] threadPool = new Thread[10];
networkLock = new Semaphore(1);
for (int i = 0; i < threadPool.length; i++)
{
threadPool[i] = new Thread(new Runnable() {
#Override
public void run() {
writeMessage(MESSAGE);
}
});
threadPool[i].start();
}
}
public static void writeMessage(String test)
{
try {
if(sock == null || sock.isClosed())
sock = new Socket(HOST, PORT);
DataOutputStream out =
new DataOutputStream(sock.getOutputStream());
System.out.println("Writting message");
//networkLock.acquire();
out.writeUTF(test);
//networkLock.release();
BufferedReader in = new BufferedReader(
new InputStreamReader(sock.getInputStream()));
System.out.println("Waiting for reply");
String input = in.readLine();
System.out.println(input);
// in.close();
// out.close();
// sock.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
When I start the client, the only output I get from the client is a "Writting message" and "Waiting for reply" a bunch of times. When I shut down the server, I finally get the responses of You said " Hellow world" along with a null or two thrown in usually. As for the server, it prints out the two print statements just fine. Do you think someone could help me out here?
The Java client is using in.readLine() which looks for a newline character in the input stream. However, the server is not writing a newline to the client socket.
So change this:
sock.write('You said "' + data + '"');
to this:
sock.write('You said "' + data + '"\n');

Web Audio API and Node.js

How would I correctly receive/send raw audio data?
I currently receive raw audio data over WebSockets (with Node.js) and write them to a file. Data is sent as byte[] array of 1024 byte in size from a Java client. Audio format is PCM, Mono, 16bit, 44100Hz.
I'm trying to pass on the raw audio data directly to browser, but it doesn't seem to work. What am I missing? Sorry for being new at this. The browsers I tested all support (Webkit) AudioContext. For each package received in browser, I get the following message:
Uncaught SyntaxError: An invalid or illegal string was specified. audio.php:19 1024
Node.js (server):
var WebSocketServer = require('ws').Server
, wss = new WebSocketServer({port: 8081});
var Clients = [];
function findClient(url) {
return (Clients.indexOf(url));
}
wss.on('connection', function(ws) {
Clients.push(ws);
console.log('Connected: %s', ws.upgradeReq.url);
console.log('Clients: %s', Clients.length);
ws.on('message', function(message, flags) {
if(flags.binary) {
ws.send(message, {binary:true});
}
console.log('data arrived: %s', message);
});
ws.on('close', function(user) {
console.log('Disconnected: %s', ws.upgradeReq.url);
Clients.splice(findClient(ws));
console.log('Clients: %s', Clients.length);
});
Client browser:
<script language="javascript">
if (window.webkitAudioContext) {
var ctx = new webkitAudioContext();
} else if (window.AudioContext) {
var ctx = new AudioContext();
}
function testSound(buff) {
var src = ctx.createBufferSource();
src.buffer = ctx.createBuffer(buff, false);
//src.looping = false;
src.connect(ctx.destination);
src.noteOn(0);
}
var ws = new WebSocket('ws://localhost:8081');
ws.binaryType = 'arraybuffer';
ws.onmessage = function(e) {
console.log(e.data.byteLength);
testSound(e.data);
}
</script>

Categories