I'm trying to implement a websocket server in node.js without using any framework.
Sending messages from client to server is working fine. But now I tried to send a text file from client to server. I can see the content on the server side by using console.log in the terminal.
But:
how can i get the file information ? (name, created/edited date, etc. ?)
how can i save the file ?
Client code:
(function () {
'use strict';
var output, ws;
//Display logging information in the document
function log(s) {
var p = document.createElement("p");
p.style.wordWrap = "break-word";
p.textContent = s;
output.appendChild(p);
//Also log information on the javascript console
window.console.log(s);
}
//Send a message on the Websocket
function sendMessage(msg) {
console.log(ws.binaryType);
ws.send(msg);
console.log("Message sent");
}
//Initialize WebSocket connection and event handlers
function setup() {
output = document.getElementById("output");
ws = new window.WebSocket("ws://localhost:9999/");
//Listen for the connection open event then call the sendMessage function
ws.onopen = function () {
console.log("Connected");
document.getElementById('fl').onchange = function() {
sendMessage(document.querySelector('input[type="file"]').files[0]);
};
sendMessage("Hello Galileo!");
}
//Listen for the close connection event
ws.onclose = function (e) {
if(this.readyState == 2){
console.log('Connection is closing (Closing Handshake).')
}
else if(this.readyState == 3){
console.log('Connection closed. Has been closed or could not be opened.')
}
else{
console.log('Unhandled ReadyState: ',this.readyState);
}
console.log("Disconnected: " +
' reason:' + e.reason +
' was clean:' + e.wasClean +
' code:' + e.code);
}
//Listen for connection errors
ws.onerror = function (e) {
console.log("Error: " + e);
}
//Listen for new messages arriving at the client
ws.onmessage = function (e) {
console.log("Message received: " + e.data);
//Close the socket once one message has arrived
ws.close();
}
}
//Start running the example
setup();
})();
HTML Code
<!DOCTYPE html>
<html>
<head>
<title>Websocket Echo Client</title>
<meta charset="utf-8"/>
</head>
<body>
<h2>Websocket Echo Client</h2>
<div id="output"></div>
<input type="file" id="fl"/>
<script src="websocket.js"></script>
</body>
</html>
Server code
switch (opcode) {
case opcodes.TEXT:
this.payload = payload.toString("utf8");
winston.log('info','Text:\r\n', this.payload);
break;
case opcodes.BINARY:
console.log('info','File:\r\n', payload.toString("utf8"));
As far as I know the payload you're receiving on the server side does not contain the meta data about the file. I believe the File object is treated as a normal Blob with some extra meta data and the ws.send is only handling it like a Blob (it has no special handling for File).
The meta data can be accessed using
document.querySelector('input[type="file"]').files[0].name
document.querySelector('input[type="file"]').files[0].size
document.querySelector('input[type="file"]').files[0].type
And then send separately.
Related
I'm trying to pass data from c# using console application to webpage using socket.io in real time
here is my c# code:
static void Main(string[] args)
{
int i = 0;
while(true)
{
//String data = Console.ReadLine();
String data = i.ToString();
if(data.Equals("exit", StringComparison.OrdinalIgnoreCase)) break; //If the user types "exit" then quit the program
SendData("127.0.0.1", 41181, data); //Send data to that host address, on that port, with this 'data' to be sent
//Note the 41181 port is the same as the one we used in server.bind() in the Javascript file.
System.Threading.Thread.Sleep(50); //Sleep for 50ms
i++;
}
}
public static void SendData(string host, int destPort, string data)
{
IPAddress dest = Dns.GetHostAddresses(host)[0]; //Get the destination IP Address
IPEndPoint ePoint = new IPEndPoint(dest, destPort);
byte[] outBuffer = Encoding.ASCII.GetBytes(data); //Convert the data to a byte array
Socket mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); //Create a socket using the same protocols as in the Javascript file (Dgram and Udp)
mySocket.SendTo(outBuffer, ePoint); //Send the data to the socket
mySocket.Close(); //Socket use over, time to close it
}
this is app.js
var app = require('http').createServer(handler);
var io = require('socket.io').listen(app);
var fs = require('fs');
var mySocket = 0;
app.listen(3000); //Which port are we going to listen to?
function handler (req, res) {
fs.readFile(__dirname + '/index.html', //Load and display outputs to the index.html file
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.on('connection', function (socket) {
console.log('Webpage connected'); //Confirmation that the socket has connection to the webpage
mySocket = socket;
});
//UDP server on 41181
var dgram = require("dgram");
var server = dgram.createSocket("udp4");
server.on("message", function (msg, rinfo) {
console.log("Broadcasting Message: " + msg); //Display the message coming from the terminal to the command line for debugging
if (mySocket != 0) {
mySocket.emit('field', "" + msg);
mySocket.broadcast.emit('field', "" + msg); //Display the message from the terminal to the webpage
}
});
server.on("listening", function () {
var address = server.address(); //IPAddress of the server
console.log("UDP server listening to " + address.address + ":" + address.port);
});
server.bind(41181);
finally this is index.html
<html>
<head>
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
</head>
<body>
<script>
var socket = io();
socket.on('field', function (data) {
$("#field").html(data);
});
</script>
Data from C#: <div id="field"></div>
</body>
</html>
I used this article to implement it, everything, seems work fine for example when I send data to console of node.js it display it but as soon as I run the page (localhost:3000) after several printing "webpage connected" it shows this error in my console:
nodemon app crashed - waiting for file changes
can someone give me a solution?
this my result picture
Error may occure on a different levels. I see that you are not listenning socket errors, both for server and io.
Both of them are based on EventEmiter approach, so both have error event to listen.
Try to listen all possible error places, this will give you additional infromation on why your app crashed.
server.on("error", err => console.error("server error occured", err));
io.on("error", err => console.error("io error occured", err));
Update
Replace in index.html script loading for socket.io with this.
<script src="/socket.io/socket.io.js"></script>.
Then, all re-connection issues should gone. I'm not pretty sure how it is working.
In the MDN documentation for WebSocket.send it says:
Exceptions thrown
INVALID_STATE_ERR
The connection is not currently OPEN.
An exception is indeed thrown when in CONNECTING state, but if the socket is closed (state is CLOSED) then I don't get any exception. This happens for all the browsers I've tried.
I've tried reading the spec but couldn't seem to find anything relevant.
Here's some reproducing code:
Clicking Create also sends before the socket is open (exception thrown)
After socket is open click Send (no exception is thrown)
Click Close and then Send (no exception is thrown, this surprises me)
var s = null;
function log(msg) {
var d = document.createElement('div');
d.textContent = (new Date().toLocaleTimeString()) +": " + msg;
document.getElementById('out').appendChild(d);
}
function create() {
log("Creating");
s = new WebSocket("wss://echo.websocket.org");
s.onopen = function() {
log("Socket opened");
}
s.onmessage = function(e) {
log("Got: " + e.data);
}
send("before open");
}
function send(msg) {
try {
log("Sending: " + msg);
s.send(msg);
log("Send didn't throw");
}
catch(e) {
log("Exception: " + e.message);
}
}
function close() {
log("Closing");
s.close();
}
document.getElementById('create').addEventListener('click', create, true);
document.getElementById('send').addEventListener('click', send.bind(null, 'manually'), true);
document.getElementById('close').addEventListener('click', close, true);
<button id="create">Create</button>
<button id="send">Send</button>
<button id="close">Close</button>
<div id="out"/>
First I built a websocket server using node js and ws module. Then using chrome and firefox, I connect to that server and the connection is successfully established. However, the message I send from browsers does not arrive at the server. I have some code on server to console.log out if message is received. Nothing appears, however when I refresh the browser, the messages I previously sent arrive. The messages did not arrive when sent them but only once I refresh the page. I don't know why. This seems to work in from some other computers but not mine.
Here is the server code:
var WebSocketServer = require('ws').Server
, http = require('http')
, express = require('express')
, app = express();
app.use(express.static(__dirname + '/views'));
var rmi = require('./RMIClient.js');
console.log(rmi);
var server = http.createServer(app);
server.listen(8080);
var wss = new WebSocketServer({server: server});
// from here is the logic codes
var clients = [];
var clientId = 0;
wss.on('connection', function(ws) {
console.log("connection established for client "+ (clients.length+1));
clients.push(ws);
console.log("index is " + clients.indexOf(ws));
clientId += 1;
ws.send("Hello Client: " + clientId);
//
// ws.send("Welcome from AMTT Chatting Server");
ws.on('message',function(data){
console.log('message receieved : '+data);
for(var i = 0;i<clients.length;i++){
clients[i].send(data);
}
});
ws.on('a',function(){
console.log("a event fire from client");
});
ws.on('close', function() {
var index = clients.indexOf(ws);
console.log('stopping client interval '+index);
if (index > -1) {
clients.splice(index, 1);
}
});
});
Here is the client code:
<html>
<script>
//var ws = new WebSocket('ws://localhost:8080/');
var messagearea,inputarea,sendButton;
var connection = new WebSocket(/*'wss://echo.websocket.org');*/'ws://192.168.8.195:8080/');
// When the connection is open, send some data to the server
console.log(connection.readyState);
connection.onopen = function () {
console.log(connection.readyState);
inputarea.disabled = false;
sendButton.disabled = false;
};
// Log errors
connection.onerror = function (error) {
console.log('sorry connection fail:' + JSON.stringify(error));
};
// Log messages from the server
connection.onmessage = function (e) {
messagearea.value = messagearea.value + '\n' + e.data;
console.log('Server: ' + e.data);
};
function sendMessage(){
if(inputarea.value !='')
connection.send(inputarea.value);
inputarea.value = '';
}
</script>
<body>
<textarea rows="15" cols="100" id="messagearea" disabled>
</textarea>
<br/>
<textarea rows="2" cols="90" id="inputarea" required autofocus>
</textarea>
<input type = 'button' value = 'send' id = 'sendbutton' onclick = "sendMessage()"/>
</body>
<script>
messagearea = document.getElementById('messagearea');
messagearea.value = '';
inputarea = document.getElementById('inputarea');
inputarea.value = '';
inputarea.disabled = true;
sendButton = document.getElementById('sendbutton');
sendButton.disabled = true;
</script>
</html>
And again I found that kind of situation when I develop that code in java and deployed in wildfly server. I am lost. I think there is something concerned with my network card. Because that same code work perfectly in my friend's machine.
Does anybody experience this situation ? or any solution?
You can also try the following:
connection.addEventListener("message", function (e) {
processSocketMessage(e);
});
good luck :)
this is my first time using websockets and I am having trouble getting my server to work. Below is the simple em-websocket server I copied from this github page. It's basically unchanged right now so it looks like so:
require 'em-websocket'
EM.run {
EM::WebSocket.run(:host => "0.0.0.0", :port => 8080) do |ws|
ws.onopen { |handshake|
puts "WebSocket connection open"
# Access properties on the EM::WebSocket::Handshake object, e.g.
# path, query_string, origin, headers
# Publish message to the client
ws.send "Hello Client, you connected to #{handshake.path}"
}
ws.onclose { puts "Connection closed" }
ws.onmessage { |msg|
puts "Recieved message: #{msg}"
ws.send("Pong: #{msg}")
}
end
}
I then copied the html from this simple echo test, just changing the url from ws://echo.websocket.org to ws://localhost:3000/websocket.rb (the .rb file is located in the app directory of my Rails project).
When I run the test from that page, I get the following results:
CONNECTED
SENT: WebSocket rocks
RESPONSE: [["client_connected",{"id":null,"channel":null,"data":{"connection_id":70297110490160},"success":null,"result":null,"server_token":null}]]
DISCONNECTED
Since the data in this test is hard-coded, I had expected the SENT and RESPONSE messages to be the same. However, I get the confusing message that begins with client_connected but contains nothing but null data.
Can anyone tell me what is going on? Am I connecting to my "server" (the websockets.rb file) and if so do I simply need to make some adjustments in the code, such as create a reply method? Again, this is my first time attempting to use this technology so I apologize if I'm missing anything in this post.
For good measure, here is the code that is running in the echo test.
<script language="javascript" type="text/javascript">
var wsUri = "ws://localhost:3000/websocket.rb";
var output;
function init() {
output = document.getElementById("output");
testWebSocket();
}
function testWebSocket() {
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) {
onOpen(evt)
};
websocket.onclose = function(evt) {
onClose(evt)
};
websocket.onmessage = function(evt) {
onMessage(evt)
};
websocket.onerror = function(evt) {
onError(evt) };
}
function onOpen(evt) {
writeToScreen("CONNECTED");
doSend("WebSocket rocks");
}
function onClose(evt) {
writeToScreen("DISCONNECTED");
}
function onMessage(evt) {
writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data+'</span>');
websocket.close();
}
function onError(evt) {
writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
}
function doSend(message) {
writeToScreen("SENT: " + message); websocket.send(message);
}
function writeToScreen(message) {
var pre = document.createElement("p");
pre.style.wordWrap = "break-word";
pre.innerHTML = message; output.appendChild(pre);
}
window.addEventListener("load", init, false);
</script>
<h2>WebSocket Test</h2>
<div id="output"></div>
</html>
this my code from books "The Definitive Guide to HTML5 websocket".
....
<div id="output"></div>
<script>
function setup() {
output = document.getElementById("output");
ws = new WebSocket("ws://localhost:7777");
ws.onopen = function(e) {
log("Connected");
sendMessage("Hello Websocket!");
}
ws.onclose = function(e){
log("Disconnected: " + e.reason);
}
ws.onerror = function(e){
log("Error ");
}
ws.onmessage = function(e) {
log("Message received: " + e.data);
ws.close();
}
}
function sendMessage(msg){
ws.send(msg);
log("Message Sent");
}
function log(s){
var p = document.createElement("p");
p.style.wordWrap = "break-word";
p.textContent = s;
output.appendChild(p);
console.log(s);
}
setup();
</script>
but, when i'm running it in localhost.. the output just like this
Connected
Message Sent
and stop until that. i knew event onmessage is not firing, but i dont know why. what could possibly be the problem? thanks
onmessage will only fire when the server sends a message to the client, not when the client is sending a message to the server (which is what you're doing).
If your server is sending back a message and that isn't being picked up by your client, you're going to need to provide a bit more context (server implementation, etc).