So I am trying to send my user's audio to a server and save it in a file with the following code (Frontend is JavaScript, and the server is Python), it doesn't seem to work with no errors in the JavaScript, and Python console and an empty output.wav file.
<script>
const socket = new WebSocket("ws://localhost:8080");
const startRecordingButton = document.getElementById("start-recording");
let mediaRecorder;
startRecordingButton.addEventListener("click", async () => {
const stream = await navigator.mediaDevices.getUserMedia({
audio: true,
});
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.start();
mediaRecorder.addEventListener("dataavailable", (event) => {
socket.send(event.data);
});
mediaRecorder.addEventListener("error", (event) => {
console.error("MediaRecorder error:", event);
});
});
</script>
<button id="start-recording">Start Recording</button>
import asyncio
import wave
import websockets
with wave.open("output.wav", "wb") as wav_file:
wav_file.setsampwidth(2)
wav_file.setnchannels(1)
wav_file.setframerate(16000)
async def handle(websocket, path):
async for message in websocket:
data = message.data
wav_file.writeframes(data)
start_server = websockets.serve(handle, "localhost", 8080)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
I've got the LTS Python, Pip, and the latest versions of the WebSocket package. I am trying to test this in the latest Google Chrome browser. What is wrong with this code?
Related
I'm building a websocket chat service, running on NodeJS. It's already working on terminal, if you want to try, check the terminal client package. https://www.npmjs.com/package/#redstone-solutions/hackerchat-client
It works fine on the terminal, now i'm developing a package to integrate web apps (javascript, react, etc), but i can't connect to the websocket via browser.
Basically, that's the backend on the websocket creation:
(I'm not using socket.io, the only dependency is uuid)
async initialize(eventEmitter: NodeJS.EventEmitter): Promise<http.Server> {
const server = http.createServer((request: http.IncomingMessage, response: http.ServerResponse) => {
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Request-Method', '*');
response.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET');
response.setHeader('Access-Control-Allow-Headers', '*');
response.writeHead(200, { 'Content-Type': 'text/plain' })
response.end('Hacker chat server is running!\n\nPlease connect with websocket protocol.')
})
server.on('upgrade', (request, socket) => {
socket.id = uuid()
const headers = [
'HTTP/1.1 101 Web Socket Protocol Handshake',
'Upgrade: WebSocket',
'Connection: Upgrade',
''
]
.map(line => line.concat('\r\n'))
.join('')
socket.write(headers)
eventEmitter.emit(EventTypes.event.NEW_USER_CONNECTED, socket)
})
return new Promise((resolve, reject) => {
server.on('error', reject)
server.listen(this.port, () => resolve(server))
})
}
Here's my try on a new react app, i'm using the same ways that i use on the terminal client.
function App() {
useEffect(() => {
async function run() {
const componentEmitter = new Events()
const connection = await createConnection()
console.log(connection)
}
run()
}, [])
async function createConnection() {
const options = {
port: '9898',
host: 'localhost',
headers: {
Connection: 'Upgrade',
Upgrade: 'websocket'
}
}
const request = http.request(options)
request.end()
return new Promise(resolve => {
request.once('upgrade', (response, socket) => resolve(socket))
})
}
return <div />
}
The request never upgrades on the react app! The console.log(connection) is never called.
I'm not sure if i'm using a resource that's not compatible with browsers (http package, for example)...
The applications are very simple/small, if you need the full code:
https://github.com/redstone-solutions/hackerchat-server
https://github.com/redstone-solutions/hackerchat-terminal-client
Any idea?
I found a way to connect with the socket, but I will need to restructure my application.
const server = new WebSocket('ws://localhost:9898')
Using the native WebSocket API from JavaScript, i can stablish a connection.
With the http library, the request never upgrades, i believe that this lib doesn't fully work on the browser.
I'm having trouble connecting 4 arduinos using serialports and NodeJs.
When I connect all the ports only one is actually working and collecting the data message while all the others are ignored.
If I declare the serial ports separately they all work fine so the problem is not the Arduino code.
Here's how i declare all the serialports:
// Load HTTP module to create server, handle requests and send back static files (html, css, js)
const http = require('http');
// Load file system module to load files from computer
const fs = require('fs');
// Load path module to read paths from urls
const path = require('path');
// Load serialport module to communicate with arduino
const SerialPort = require('serialport');
// Open up connection with Arduino board
const serial = new SerialPort('/dev/cu.usbserial-1411140', {
baudRate: 115200
}, function() {
console.log('1411140 ready');
})
const SerialPort1 = require('serialport');
const serial1 = new SerialPort1('/dev/cu.usbserial-141120', {
baudRate: 115200
}, function() {
console.log('141120 ready');
})
const SerialPort2 = require('serialport');
const serial2 = new SerialPort2('/dev/cu.usbmodem-1411301', {
baudRate: 115200
}, function() {
console.log('1411301 ready');
})
const SerialPort3 = require('serialport');
const serial3 = new SerialPort3('/dev/cu.usbserial-1411130', {
baudRate: 115200
}, function() {
console.log('1411130 ready');
})
// Define port on which the webpage will be served from
const port = 8080;
This is how i read the arduino data
const io = require('socket.io')(server);
// do stuff when a client connects
io.on('connection', (socket) => {
console.log('a new client connected');
// let the client know that it's connected
socket.emit('greetings', 'You are now connected to the server through Socket IO');
// when receiving data from Arduino, tell the client what to do accordingly
serial.on('data', forwardMessage);
// log if an user disconnects
socket.on('disconnect', () => {
console.log('client disconnected');
// remove listener from Node EventEmitter
serial.removeListener('data', forwardMessage);
});
function forwardMessage(data) {
let message = data.toString().replace(/\n*/, '');
//riceve messaggi dal device corrispondente. Attenzione al nome messo anche sul codice Arduino
if (message.includes('Coinv')) {
socket.emit('CoinvChange', message.substring(7));
}
if (message.includes('Impor')) {
socket.emit('ImporChange', message.substring(7));
}
if (message.includes('Piace')) {
socket.emit('PiaceChange', message.substring(7));
}
if (message.includes('Cresc')) {
socket.emit('CrescChange', message.substring(7));
}
if (message.includes('Press')) {
socket.emit('PressChange', message.substring(7));
}
}
});
And finally this is how i use the message
const socket = io();
// log on browser console when socket is connected to server
socket.on('greetings', (message) => {
console.log(message);
});
// Caricamento Petali
socket.on('CoinvChange', (message) => {
console.log('coinv');
if(message<=6){
getFlowerObject ("petali", 1);
}
if(message>7 && message <=9) {
getFlowerObject ("petali", 2);
}
if(message>12) {
getFlowerObject ("petali", 3);
}
});
// Caricamento Sepali
socket.on('ImporChange', (message) => {
console.log('Impor');
if(message<=2){
getFlowerObject ("sepali", 1);
}
if(message>3 && message <=7) {
getFlowerObject ("sepali", 2);
}
if(message>8) {
getFlowerObject ("sepali", 3);
}
});
Thank you for your help!
Well, in the second snipped, you call just serial.on('data', forwardMessage);, and serial just refers to the firt one.
If you want to interact with the other ones, you have to call the same method also on serial1, serial2 and serial3, which you never use, instead.
As a sidenote, it's enugh to use const SerialPort = require('serialport'); just at the beginning (of the first snippet), then you can do
const serial1 = new SerialPort(...)
...
const serial2 = new SerialPort(...)
...
I have the following situation:
I want to get the console log of a website and send that to WebSocket clients.
I was able to create a node server and send data to connected users with below code.
const puppeteer = require('puppeteer');
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 2222 });
wss.on('connection', function connection(ws) {
ws.send("sending the sample data");
});
I was able to get the console log of website using following code:
(async () => {
const browser = await puppeteer.launch({
args: [
'--no-sandbox',
'--headless',
'--disable-gpu',
'--window-size=1920x1080'
]
});
const page = await browser.newPage();
await page.goto('https://example.com/test.php');
page.on('console', msg => console.log(msg.text()));
})();
Here page.on is a callback function, which is called every time there is a console log. How do I broadcast that msg (console.log from puppeteer) to WebSocket clients?
Please note that the website is opened once only when the app is started and console.log output is generated using setInterval every second. So new users get only the latest data.
Instead of console.log(msg.text()) you need to broadcast the message to all ws clients, right?
So a simple code will be:
page.on('console', msg => {
wss.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
client.send(msg.text());
}
});
});
Read here for more info
I'm runing a localhost adonisjs project with a websocket. I followed the adonis get started here. Everything in the server looks ok, but when I tried to connect in my react-native application a got this error:
{
"isTrusted": false,
"message": "Expected HTTP 101 response but was '400 Bad Request'",
}
This is my cliente code:
const ws = new WebSocket("ws://192.168.0.11:3333")
ws.onopen = () => {
ws.send(JSON.stringify({
t: 1,
d: { topic: 'prelista:5999c0ea-6bbb-4e0f-9496-f62658bbac5' }
}))
}
ws.onmessage = (e) => {
console.log(e)
}
ws.onerror = (event) => {
console.log(event)
}
This is my server code:
'use strict'
const Ws = use('Ws')
Ws.channel('prelista:*', ({ socket }) => {
console.log(socket.topic)
})
I found my mistake. Whe we use Adonis websocket on the server side, we need to add /adonis-ws in the end of ws path. Well, changed this const ws = new WebSocket("ws://192.168.0.11:3333")
to this const ws = new WebSocket("ws://192.168.0.11:3333/adonis-ws")
worked now 👍
I have written the following tcp client in nodejs.
const net = require('net');
const HOST = 'linux345';
const PORT = 2345;
let ErrCode = 1;
const client = new net.Socket();
client.connect(PORT, HOST, function() {
ErrCode = 0;
});
client.on('data', function(data) {
console.log('Client received: ' + data);
if (data.toString().endsWith('exit')) {
client.destroy();
}
});
client.on('close', function() {
});
client.on('error', function(err) {
ErrCode = err.code;
console.log(ErrCode);
});
console.log(ErrCode);
Please suggest how can I write same logic using async/await
I have looked into the following post but it is not helpful.
node 7.6 async await issues with returning data
There is an amazing package that wraps the native Node socket in a promise. Allowing you to utilize async/await syntax on all socket methods.
The package can be found on NPM.
Example
import net from "net"
import PromiseSocket from "promise-socket"
const socket = new net.Socket()
const promiseSocket = new PromiseSocket(socket)
await connect(80, "localhost")
// or
await connect({port: 80, host: "localhost"})