esp8266 websocket server and sodcket.io client in angular 7 - c++

I am using esp8266 to run my websocket server and angular 7 to run socket.io to run websocket client. When I run the angular application. The logs in Arduino shows Disconnected!. I am not sure what is causing this.
following is the angular side code for client.
import * as io from 'socket.io-client';
import { Observable } from 'rxjs/Observable';
import * as Rx from 'rxjs/Rx';
import { environment } from 'src/environments/environment';
#Injectable()
export class SocketServiceService {
private socket;
constructor() { }
connect(): Rx.Subject<MessageEvent> {
this.socket = io('ws://192.168.43.155:81');
console.log("created server")
let observable = new Observable(observer => {
this.socket.on('message', (data) => {
console.log("Received message from Websocket Server")
observer.next(data);
})
return () => {
this.socket.disconnect();
}
});
let observer = {
next: (data: Object) => {
this.socket.emit('message', JSON.stringify(data));
console.log("msg emited"+ data);
},
};
return Rx.Subject.create(observer, observable);
}
}
this is esp8266 code
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsServer.h>
#include <Hash.h>
ESP8266WiFiMulti WiFiMulti;
WebSocketsServer webSocket = WebSocketsServer(81);
#define USE_SERIAL Serial1
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
switch(type) {
case WStype_DISCONNECTED:
USE_SERIAL.printf("[%u] Disconnected!\n", num);
break;
case WStype_CONNECTED:
{
IPAddress ip = webSocket.remoteIP(num);
USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
webSocket.sendTXT(num, "Connected");
}
break;
case WStype_TEXT:
USE_SERIAL.printf("[%u] get Text: %s\n", num, payload);
break;
case WStype_BIN:
USE_SERIAL.printf("[%u] get binary length: %u\n", num, length);
hexdump(payload, length);
break;
}
}
void setup() {
USE_SERIAL.begin(115200);
USE_SERIAL.setDebugOutput(true);
USE_SERIAL.println();
USE_SERIAL.println();
USE_SERIAL.println();
for(uint8_t t = 4; t > 0; t--) {
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
USE_SERIAL.flush();
delay(1000);
}
WiFiMulti.addAP("SSID", "passpasspass");
while(WiFiMulti.run() != WL_CONNECTED) {
delay(100);
}
webSocket.begin();
webSocket.onEvent(webSocketEvent);
}
void loop() {
webSocket.loop();
}
please Suggest what might be going wrong, Any pointers will be helpful.

It's a lot to ask for someone to actually try to debug this (to do so, I'd have to create an Angular project using your Angular code, and also set up an ESP8266 sketch using your Arduino code), so I'm not going to try, but here's a couple of suggestions:
Try setting up a WebSocket server in Node, using the example code in the socket.io-client documentation. If that works, then you've narrowed the problem down to the ESP8266 code. If it fails in the same way, then you have a problem in your Angular client.
If the problem is in your Angular code, I'd suggest using the rsjx WebSocketSubject class. It gives you a fully configured WebSocket client, works really well, and would eliminate your low-level websocket client code.
Here's an example of connecting to the WebSocket, subscribing to inbound messages, and sending an outbound message:
connect() {
this.webSocket = webSocket(environment.chatUrl);
this.subscription = this.webSocket.subscribe(msg => {
console.log('got message: ' + msg);
},
err => {
this.setDisconnected();
console.log('err!', err);
},
() => {
console.log('websocket closed'));
this.setDisconnected();
}
);
this.webSocket.next({
name: this.name
});
}
and here's sending a message:
sendMessage(msg: string) {
if (this.connected) {
this.webSocket.next(msg);
}
}
and here's disconnecting:
private disconnect() {
if (this.subscription) {
this.webSocket.complete();
this.subscription.unsubscribe();
this.subscription = undefined;
this.setDisconnected();
}
}

Related

How to handle errors in websocket in jest end to end test?

I have one file which runs server on start. And there is one function to upgrade the connection based on some checks of the request.
//A.ts
export abstract class A{
protected _server: http.Server;
protected _wss: WebSocket.Server;
constructor(){
this._wss = new WebSocket.Server({ noServer: true });
}
async start(port: number) {
await this.startServer(port);
await this.startUpgardeListener();
await this.startWsConnectionListener();
}
private async startServer(port: number) {
this._server.listen(port, () => {
Logger.log(`Server started on port ` + port);
});
}
private async startUpgardeListener() {
this._server.on("upgrade", async (request: http.IncomingMessage, clientSocket, head: Buffer) => {
return await this.upgradeHandler(request, clientSocket as Socket, head);
});
}
private async startWsConnectionListener() {
this._wss.on('connection', async (clientWebSocket: WebSocket, request: http.IncomingMessage) => {
return await this.connectionHandler(clientWebSocket, request);
});
}
protected abstract upgradeHandler(request: http.IncomingMessage, clientSocket: Socket, head: Buffer): Promise<void>;
protected abstract connectionHandler(clientWebSocket: WebSocket, request: http.IncomingMessage): void;
}
//B.ts
export class FESProxy extends Proxy {
private _c = new H();
protected async upgradeHandler(request: IncomingMessage, clientTcpSocket: Socket, head: Buffer): Promise<void> {
let resource;
try{
this.initHandlers();
this.create(resource);
}
catch(e){
resource = this.cleanup(clientTcpSocket, resource);
}
}
private async create(resource){
resource = await this._c.createResource(resource);
if(resource.status === 400)
{
error = new Error(400);
throw error;
}
return true;
}
private initHandlers(resource: Resource, clientTcpSocket: Socket) {
this.initOnClose(clientTcpSocket, resource);
this.initOnError(clientTcpSocket, resource);
}
private initOnClose(clientTcpSocket: Socket, resource: Resource | undefined) {
clientTcpSocket.on('close', (err) => {
console.log(`Client TCP Socket Close Handler`);
resource = this.cleanup(clientTcpSocket, resource);
});
return resource;
}
private initOnError(clientTcpSocket: Socket, resource: Resource | undefined) {
clientTcpSocket.on('error', (e) => {
Logger.error(`Client TCP Socket Error Handler);
resource = this.cleanup(clientTcpSocket, resource);
});
return resource;
}
}
// B.spec.ts
let b : B;
let wb : WebSocket;
let workerServer : WebSocketServer;
describe("B test", () => {
beforeEach(async () => {
b = new B();
await b.start(3000);
})
afterEach(async () => {
wb.close();
workerServer.close();
b["_server"]?.close(()=>{});
});
it("Should handle 400 error in create call", async () => {
let resource = new Resource();
resource.status = 400;
const spiedOncreate = await jest.spyOn(b["_c"],"createResource").mockReturnValue(Promise.resolve(resource));
let uri = 'ws://localhost:3000/ws';
wb = new WebSocket(uri);
wb.on('error' ,(err) => {
console.log(err);
})
wb.on('close',() => {
})
wb.on('message',(e) =>{
console.log("Message in the socket ",e);
})
expect(spiedOncreate).toBeCalledTimes(1);
})
})
On running the test, I am getting this message
Expected number of calls: 1
Received number of calls: 0
Although I checked that catch block was called in the upgradeHandler method of B class with the status code of resource as 400. Which means that the createResource was called and with the status 400 which I set in the test only.
I also found that on error handler of websocket inside the test got triggered and got the message in the console
Error: Unexpected server response: 400
I am not able to see any other console logs if I put after assertion statement in the test. I guess my test is getting crashed and the error is not handled but not sure here. I added handlers in the test for websockets but still not working.
What am I missing or doing wrong to assert on the spyOn as I am not receiving the expected number of calls?

Expo Google Authentication doesn't work on production

I implemented Expo Authentication on my app, following the code from the doc https://docs.expo.io/guides/authentication/#google.
On local with the Expo client its working fine, in the IOS simulator and also in the web browser but when I build the app (expo build android) and try on my Android phone, the Google popup comes, I put my id and it send me back to the login page but NOTHING happen.
I put some alert to understand what was going on but I dont even get any, useEffect doesn't fire, responseGoogle doesnt seem to change.
const [requestGoogle, responseGoogle, promptAsyncGoogle] =
Google.useAuthRequest({
expoClientId:
"my_id",
androidClientId:
"my_id,
webClientId:
"my_id",
});
useEffect(() => {
alert("useEffect fired (Google)");
if (responseGoogle?.type === "success") {
const { authentication } = responseGoogle;
// success
alert("success : "+JSON.stringify(responseGoogle));
// some code to check and log the user...
} else {
alert('no success : '+JSON.stringify(responseGoogle));
}
}, [responseGoogle]);
Any idea ?
Apparently its a know bug so here is not the answer but an alternative with expo-google-sign-in :
import * as GoogleSignIn from "expo-google-sign-in";
async function loginWithGoogle() {
try {
await GoogleSignIn.askForPlayServicesAsync();
const { type, user } = await GoogleSignIn.signInAsync();
if (type === "success") {
alert(JSON.stringify(user));
}
} catch ({ message }) {
toast.show("Erreur:" + message);
alert("login: Error:" + message);
}
}

my smart contract is not responding and error saying web3 is not defined

[error saying web3 is not defined][1]<script>
var myContract;
async function CheckMetamaskConnection() {
// Modern dapp browsers...
if (window.ethereum) {
window.web3 = new Web3(window.ethereum);
try {
// Request account access if needed
await ethereum.enable();
// Acccounts now exposed
return true;
} catch (error) {
// User denied account access...
return false;
}
}
// Legacy dapp browsers...
else if (window.web3) {
window.web3 = new Web3(web3.currentProvider);
// Acccounts always exposed
return true;
}
// Non-dapp browsers...
else {
console.log('Non-Ethereum browser detected. You should consider trying MetaMask!');
return false;
}
}
$(document).ready(async function () {
var IsMetamask = await CheckMetamaskConnection();
if (IsMetamask) {
myContract = await web3.eth.contract(SmartContractABI).at(SmartContractAddress);
getCandidate(1);
getCandidate(2);
await myContract.eventVote({
fromBlock:0
}, function(err, event){
console.log("event :", event);
getCandidate(event.args._candidateid.toNumber());
});
console.log("myContract :", myContract);
console.log("Metamask detected!")
} else {
console.log("Metamask not detected");
Swal.fire({
icon: 'error',
title: 'Oops...',
text: 'Metamask not detected!',
onClose() {
location.reload();
}
});
}
});
async function getCandidate(cad){
await myContract.candidates(cad, function(err, result){
if (!err) {
console.log("result : ", result);
document.getElementById("cad" + cad).innerHTML = result[1];
document.getElementById("cad"+cad+'count').innerHTML = result[2].toNumber();
}
});
}
async function Vote(cad){
await myContract.vote(cad, function(err, result){
if(!err){
console.log("We are winning!");
} else{
console.log("Can not connect to the smart contract");
}
})
}
</script>`
i have node.js and metamask in my system(windows 10)
i cloned you project from github and runned it by following command
npm install
node index.js
the UI deployed perfectly in localhost:3000 but when i try to vote the transaction is not working!!!
then i saw content on smart contract is not rendering!!!
then i checked metamask , which was connected and have 1 ether on ropsten network!!!
then i try ganache (local blockchain provider) and still the transaction is not working!!!
then i paste the smart contract in remix and get the ABI and smart contract address and still not working!!!
then i goto developer tool of browser and saw below error!!!!...i have no idea of this error!!!!...how can i solve this???
The error can be happening because the loading of Web3. Please, try this function:
async loadWeb3(){
if(window.ethereum){
window.web3 = new Web3(window.ethereum)
await window.ethereum.request({ method: 'eth_requestAccounts' })
}
else if(window.web3){
window.web3 = new Web3(window.ethereum)
}
else{
window.alert("Non-Ethereum browser detected. You should consider trying MetaMask!")
}
}
Also, do not forget to add the import on your javascript class:
import Web3 from 'web3'
and install the import with the npm:
npm i web3 --save

Multiple websockets in QML

I understand that it's probably a trivial question but maybe someone knows how to handle multiple websocket clients in server-qml. I did not understand from the official documentation of Qt as NOT using the C++ function or webchannel to do it. Is it possible?
I have a websocket client and server in the program. If I connect from js code to html page(from the simplechat example) how do I send a socket inside the QML app and back. How to handle the name of each socket on the server and send to it the desired text. I would appreciate any help.
My current code.
WebSocketServer {
id: server
listen: true
port:1234
onClientConnected: {
webSocket.onTextMessageReceived.connect(function(message) {
appendMessage(qsTr("Server received message: %1").arg(message));
webSocket.sendTextMessage(qsTr("Hello Client!"));
// how to get a list of sockets and an instance of a particular connected socket
});
}
onErrorStringChanged: {
appendMessage(qsTr("Server error: %1").arg(errorString));
}
}
WebSocket {
id: socket
url: server.url
active:true
onTextMessageReceived: appendMessage(qsTr("Client received message: %1").arg(message))
onStatusChanged: {
if (socket.status == WebSocket.Error) {
appendMessage(qsTr("Client error: %1").arg(socket.errorString));
} else if (socket.status == WebSocket.Closed) {
appendMessage(qsTr("Client socket closed."));
}
}
}
The problem is that there is a page with the following code something like a chat client
var wsUri = "ws://localhost:1234";
var websocket = null;
function initWebSocket() {
try {
if (typeof MozWebSocket == 'function')
WebSocket = MozWebSocket;
if ( websocket && websocket.readyState == 1 )
websocket.close();
websocket = new WebSocket( wsUri );
websocket.onopen = function (evt) {
debug("CONNECTED");
};
websocket.onclose = function (evt) {
debug("DISCONNECTED");
};
websocket.onmessage = function (evt) {
console.log( "Message received :", evt.data );
debug( evt.data );
};
websocket.onerror = function (evt) {
debug('ERROR: ' + evt.data);
};
} catch (exception) {
debug('ERROR: ' + exception);
}
}
Its websocket creates client and connects to the server described. When a client connects from a js script, it can send a message to the server and take QML will be displayed in the hearth of the page. When a new client socket inside QML application connects to the server and sents to the alias in the message QML server and can receive messages from the server. But how to do so from the socket in the application message reached the customer at the js and back. To do this, probably it is necessary to the server as a defined desired socket, take the instance
webSocket.sendTextMessage(qsTr("Hello Client!"));
of the socket it is

The system crashes and can not display the error message

assume the code is correct and webservice timeout occurs.
The problem :
The system crashes and can not display the error message.
How to display error message? So I can provide an alternative to user when there is an error?
1)
I add this Class in the project :
public class MyClass
{
public static async Task LogInSuccess()
{
try
{
-- calling a web service here
}
catch (System.Exception _ex)
{
_strErrorMsg = _ex.InnerException.Message;
throw new Exception("LogInSuccess() " + _strErrorMsg);
}
}
}
--- In the MainPage,
2)
private async void SetUp ()
{
-- code for doing setUp task--
CallWebSvc();
}
3)
private void CallWebSvc()
{
bool ShowError = false;
System.Exception MyException = new Exception();
try
{
-- calling a web service thru the MyClass
System.Threading.Tasks.Task _blnLogInSuccess = MyClass.LogInSuccess();
await _blnLogInSuccess;
if (_blnLogInSuccess.IsCompleted)
{
g_blnLoginStatus = _blnLogInSuccess.Result;
}
}
catch (System.Exception _ex)
{
ShowError = true;
MyException = ex;
}
if (ShowError)
{
var MyMessageBox = new Windows.UI.Popups.MessageDialog("Remote Login Error:" + MyException.Message, "Start Login" );
await MyMessageBox.ShowAsync();
}
}
I assume your CallWebSvc method is async void (as, without async you cannot perform an await) If this is the case, you need to know async void doesn't do the same treatament to exceptions as async task. they aren't catched correctly. If you change your CallWebSvc from async void to async Task, you are going to receive the exception correctly.