I'm trying to send recordRTC blob via websocket to my Java server, my goal is to build a video stream service.
However, when the server received the blob, and write file, the web page would refresh, cause recordRTC stopped and socket disconnct.
Used package
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.4.0</version>
</dependency>
The following is my code.
Server side
public void onMessage( WebSocket conn, ByteBuffer message ) {
byte[] bytes = new byte[message.remaining()];
message.get(bytes, 0, bytes.length);
if(bytes.length > 0) {
OutputStream os = null;
UUID uuid = UUID.randomUUID();
String id=uuid.toString();
String filename =id.replace("-", "");
try {
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(
new File("./uploads/"+filename +".webm")));
bos.write(bytes);
bos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client side
function startCapture() {
logElem.innerHTML = "";
try {
videoElem.srcObject = navigator.mediaDevices.getDisplayMedia(displayMediaOptions).then(
(stream)=>{
console.log(stream);
recordRTC = RecordRTC(stream);
recordRTC.startRecording();
// blob segment and send every 3 second
recording = setInterval(()=>{
recordRTC.stopRecording(()=>{
console.log("BLOB : ", recordRTC.getBlob());
recordRTC.getBlob().arrayBuffer().then((val)=>{
console.log("BLOB : ", recordRTC.getBlob());
socket.send(val);
});
})
recordRTC.startRecording();
}, 3000);
videoElem.srcObject = new MediaStream(stream);
});
} catch (err) {
console.error("Error: " + err);
}
}
reload event picture
I found the reload EVENT occur after the fisrt blob sent and write to file, but I don't know why the event happend.
If server don't write blob to file, just receive it, the websocket and web would work perfectly without reloading.
How could I solve the reload EVENT problem?
Thanks
Related
I wrote a C# listener that listens on a port and prints everything it recieves, and it works perfectly but when i used a JS client to send that data something get recieved but nothing gets written to the console
My C# code:
while (true)
{
TcpClient client = null;
NetworkStream stream = null;
try
{
client = listener.AcceptTcpClient();
stream = client.GetStream();
using (StreamWriter writer = new StreamWriter(stream, Encoding.ASCII) { AutoFlush = false })
{
using (StreamReader reader = new StreamReader(stream, Encoding.ASCII))
{
while (true)
{
string inputLine = "";
while (inputLine != null)
{
inputLine = reader.ReadLine();
Console.WriteLine(inputLine);
Console.WriteLine(Encoding.UTF8.GetString(Encoding.ASCII.GetBytes(inputLine)));
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
if (stream != null)
{
stream.Close();
}
if (client != null)
{
client.Close();
}
}
Console.WriteLine("Verbinding met client verbroken");
}
const net = require('net');
const client = new net.Socket();
client.connect(1234, '192.168.2.13', () => {
console.log('Connected to server');
client.write("Hello server\r");
});
I tried running a netcat listener and that worked with my JS program, I also set breakpoints in my code and concluded that when i send something with my JS code it indeed gets recieved by my server but not processed.
Your server/listener tries to read a complete line ('reader.ReadLine()').
This means, your JS client must send some "line end" marker. "Line end" is newline '\n' (although documentation specifies apparently non-working alternatives).
So socket.write("Hello server\n") should work.
Hello I'm currently implementing a websocket component to my very basic site. I'm running .NET Core 3.1 HTTP Listener for serving html, I've been stumped by implementing websockets.
I've worked with TCP in C# before and understand the flow of everything but websockets are a new thing to me. Here is the C# code for accepting websockets
[Route("/socket", "GET")]
public static async Task upgrade(HttpListenerContext c)
{
if (!c.Request.IsWebSocketRequest)
{
c.Response.StatusCode = 400;
c.Response.Close();
return;
}
try
{
var sock = (await c.AcceptWebSocketAsync(null)).WebSocket;
byte[] buff = new byte[1024];
var r = await sock.ReceiveAsync(buff, System.Threading.CancellationToken.None);
}
catch (Exception x)
{
Console.WriteLine($"Got exception: {x}");
}
//WebSocketHandler.AddSocket(sock);
}
I've added var r = await sock.ReceiveAsync(buff, System.Threading.CancellationToken.None); to this function because originally I was getting the exception in my WebSocketHandler class, so I moved the code to the one function to test.
Here is the client:
<script>
let socket = new WebSocket("ws://localhost:3000/socket");
socket.onopen = function (event) {
console.log("[ OPENED ] - Opened Websocket!");
};
socket.onclose = function (event) {
console.log("[ CLOSED ] - Socket closed");
};
socket.onerror = function (error) {
console.log("[ ERROR ] - Got websocket error:");
console.error(error);
};
socket.onmessage = function (event) {
// This function will be responsible for handling events
console.log("[ MESSAGE ] - Message received: ");
const content = JSON.parse(event.data);
console.log(content);
};
</script>
Here is the output in the console for the client:
Navigated to http://127.0.0.1:5500/index.html
index.html:556 [ OPENED ] - Opened Websocket!
index.html:569 [ CLOSED ] - Socket closed
And here is the exception from the C# server:
Got exception: System.Net.WebSockets.WebSocketException (997): The remote party closed the WebSocket connection without completing the close handshake.
at System.Net.WebSockets.WebSocketBase.WebSocketOperation.Process(Nullable`1 buffer, CancellationToken cancellationToken)
at System.Net.WebSockets.WebSocketBase.ReceiveAsyncCore(ArraySegment`1 buffer, CancellationToken cancellationToken)
at SwissbotCore.HTTP.Routes.UpgradeWebsocket.upgrade(HttpListenerContext c) in C:\Users\plynch\source\repos\SwissbotCore\SwissbotCore\HTTP\Routes\UpgradeWebsocket.cs:line 29
I can provide the http requests that the client sends if need be but I am completely stumped on this, any help will be greatly appreciated.
You might want to read up on The Close Handshake in Section 1.4 in RFC 6455 and also Close the WebSocket Connection in Section 7.1.1 in RFC 6455.
Essentially, you need to let the WebSocket endpoint know you are going to close the socket, before you terminate the socket.
For your server side, you should probably be catching this exception, as this can also happen in production scenarios when network issues occur.
I'm not sure why, but, if you change the code inside try block to this:
try
{
var sock = (await c.AcceptWebSocketAsync(null)).WebSocket;
byte[] buff = new byte[1024];
await Listen(sock);
}
catch (Exception x)
{
Console.WriteLine($"Got exception: {x}");
}
private async Task Listen(WebSocket sock)
{
return new Task(async () =>
{
while(sock.State == WebSocketState.Open)
{
var r = await sock.ReceiveAsync(buff, System.Threading.CancellationToken.None);
}
});
}
it's gonna work out fine.
I'm making a live connection between a Socket Server (Java) and a Socket Client (NodeJS). This is for a webinterface.
I can send data from NodeJS to Java, but not the other way around. I commented in the code, which positions I mean. I tried it already like you see with out.write("Hello World\n"); (with flush, of course). I tried also with out.println("Hello World"); (with flush, of course).
public class WebHandler {
private ServerSocket server;
private static Socket sock;
public void listen(int port) {
try {
server = new ServerSocket(port);
} catch (IOException e) {
System.out.println("Could not listen on port " + port);
System.exit(-1);
}
Bukkit.getScheduler().scheduleSyncRepeatingTask(Main.getPlugin(), new BukkitRunnable() {
#Override
public void run() {
try {
System.out.println("Waiting for connection");
final Socket socket = server.accept();
sock = socket;
final InputStream inputStream = socket.getInputStream();
final InputStreamReader streamReader = new InputStreamReader(inputStream);
BufferedReader br = new BufferedReader(streamReader);
// readLine blocks until line arrives or socket closes, upon which it returns null
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
WebHandler.sendMessage();
} catch (IOException e) {
System.out.println("Accept failed: " + port);
System.exit(-1);
}
}
}, 0, 100);
}
// CRITICAL
public static void sendMessage() {
try {
PrintWriter out = new PrintWriter(sock.getOutputStream());
out.write("Hello World from Java!" + "\n");
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
var net = require('net');
var client = net.connect(9090, 'localhost');
client.setEncoding('utf8');
setInterval(function() {
console.log("Writing....")
var ret = client.write('Hello from node.js\n');
console.log("Wrote", ret)
}, 5000);
// CRITICAL
client.on('data', function(data) {
console.log('Received: ' + data);
});
Please don't let you distract because of the Bukkit.getScheduler()... It's only a Task Manager. Thanks in advance :D
You don't receive a message from java because you have set an interval which will always send messages to the server and the server will be stuck in the while loop.
I would suggest to stop the interval at some point so that sendMessage() will be called.
I'm making a website with a game on it. For the game i need to send data trought sockets. Everything is working fine with loading the page but I can't get the handshaking to work.
class ServerClient {
public ServerClient() {
handshake();
}
private void handshake() {
try {
String line;
String key = "";
boolean socketReq = false;
while (true) {
line = input.readLine();
if (line.startsWith("Upgrade: websocket"))
socketReq = true;
if (line.startsWith("Sec-WebSocket-Key: "))
key = line;
if (line.isEmpty())
break;
}
if (!socketReq)
socket.close();
String encodedKey = DatatypeConverter.printBase64Binary(
MessageDigest.getInstance("SHA-1")
.digest((key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").getBytes()));
System.out.println(encodedKey);
output.println("HTTP/1.1 101 Switching Protocols");
output.println("Upgrade: websocket");
output.println("Connection: Upgrade");
output.println("Sec-WebSocket-Accept: " + encodedKey);
output.flush();
output.close(); // output = new PrintWriter(
// Socket.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
}
}
The socketReq variable is there because I don't want anyone to connect to localhost:25580 straight from their browser.
My send and receive functions are in different Threads and they will be started after the handshake.
The result of new WebSocket("ws://localhost:25580") in JS is
WebSocket connection to 'ws://localhost:25580/' failed: Error during WebSocket handshake: net::ERR_CONNECTION_CLOSED
I was having
Error during WebSocket handshake: Incorrect 'Sec-WebSocket-Accept' header value
but I guess I changed something in the code.
I searched for hours trought Article 1 and Article 2 and from other sites. Just couldn't get the whole thing to work properly.
I don't get the point of the keys and why we have to encode them.
The socket is connected to the browser and I am getting the headers from it.
Host: localhost:25580
Sec-WebSocket-Key: iWLnXKrA3fLD6h6UGMIigg==
How does the handshaking work?
You are getting a net::ERR_CONNECTION_CLOSED error, because you are closing the connection with output.close().
If you want to keep the connection open, obviously don't close it during a handshake.
Done!
Found the answers from http://blog.honeybadger.io/building-a-simple-websockets-server-from-scratch-in-ruby/ and It's working perfectly!
The code:
public ClientSocket(Socket socket) {
try {
this.socket = socket;
this.input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.output = new PrintWriter(socket.getOutputStream());
handshake();
}
private void handshake() {
try {
String line;
String key = "";
while (true) {
line = input.readLine();
if (line.startsWith("Sec-WebSocket-Key: ")) {
key = line.split(" ")[1];
System.out.println("'" + key + "'");
}
if (line == null || line.isEmpty())
break;
}
output.println("HTTP/1.1 101 Switching Protocols");
output.println("Upgrade: websocket");
output.println("Connection: Upgrade");
output.println("Sec-WebSocket-Accept: " + encode(key));
output.println();
output.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
private String encode(String key) throws Exception {
key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
byte[] bytes = MessageDigest.getInstance("SHA-1").digest(key.getBytes());
return DatatypeConverter.printBase64Binary(bytes);
}
Now I just have to decode the messages.
I have been trying to transfer audio files between my android app and my node-webkit app but I'm new to the world of socket.io/nodejs/delivery.js.
Here is my code:
android-code ERROR-LINE: os.write(mybytearray, 0, mybytearray.length);
protected Void doInBackground(Void... arg0) {
Socket sock;
try {
// sock = new Socket("MY_PCs_IP", 1149);
sock = new Socket("192.168.0.10", 5001);
System.out.println("Connecting...");
// sendfile
File myFile = new File(this.currentSong.getPath());
byte[] mybytearray = new byte[(int) myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray, 0, mybytearray.length);
OutputStream os = sock.getOutputStream();
System.out.println("Sending...");
os.write(mybytearray, 0, mybytearray.length);
os.flush();
System.out.println("Sended..");
// RESPONSE FROM THE SERVER
BufferedReader in = new BufferedReader(
new InputStreamReader(sock.getInputStream()));
in.ready();
String userInput = in.readLine();
System.out.println("Response from server..." + userInput);
sock.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
node-webkit-code
var io = require('socket.io').listen(5001),
dl = require('delivery'), //delivery.server
fs = require('fs');
io.sockets.on('connection', function(socket){
delivery = dl.listen(socket);
delivery.on('receive.success',function(file){
fs.writeFile("music/"+file.name,file.buffer, function(err){
if(err){
console.log('File could not be saved.');
}else{
console.log('File saved.');
addSong("music/"+file.name);
};
});
});
});
Note: My server side works well it's already tested by a js client
This is the error I am getting:
Android side Error:
08-28 14:56:36.180: W/System.err(30510): java.net.SocketException: sendto failed: EPIPE (Broken pipe)
08-28 14:56:36.180: W/System.err(30510): at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:499)
08-28 14:56:36.180: W/System.err(30510): at libcore.io.IoBridge.sendto(IoBridge.java:468)
08-28 14:56:36.180: W/System.err(30510): at java.net.PlainSocketImpl.write(PlainSocketImpl.java:507)
So maybe I'm wrong trying to do a bad connection because of protocols.. between a socket and socket.io..?
if any one can help my out I will be pleased. I already looked around but as I said I'm new to this world and I get hazy
basically my question is: What's wrong? and How I accomplish my objective?
Thanks for your time
I am using com.koushikdutta.async.http.socketio.SocketIOClient
there is some problems with this library and socket.io but it it's solved by using this dependency on node-webkit
"socket.io": "~0.9",
also need to read file->base64 codification-> then emit the string on the server side must do this:
socket.on('finishFileTransfer',function(){
fs.writeFile("music/"+fileName,new Buffer(file,'base64'), function(err){
if(err){
console.log('File could not be saved.');
}else{
console.log('File saved.');
addSong("musica/"+fileName);
}
file = "";
fileName = null;
});
});