1.here is my websocket.service.ts file
import { Injectable } from '#angular/core';
import { Observable, } from 'rxjs';
import {io} from 'socket.io-client';
#Injectable({
providedIn: 'root'
})
export class WebsocketService {
socket: any;
readonly uri: string = "ws://localhost:3000";
constructor() {
this.socket = io(this.uri);
}
listen(eventName: string, data:any){
return new Observable((subscriber) => {
this.socket.on(eventName, (data) => {
subscriber.next(data)
})
})
}
emit(eventName: string , data: any){
this.socket.emit(eventName,data);
}
}
here is my app.components.ts file
import { Component, OnInit } from '#angular/core';
import { WebsocketService } from './websocket.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'socket-io-example';
constructor( private websockerservice: WebsocketService){
}
ngOnInit(){
// here we want to listen to an event from socket.io server
this.websockerservice.listen('test event','data').subscribe((data) =>{
console.log(data);
})
}
}
here is my node.js, socket-io.server.js file
var server = require('http').Server(app); //here i got refernce error: app is not defined
~~~
var io = require('socket.io')(server);
io.on('connection', function(socket){
console.log("A user cconnected");
socket.emit('test event', 'here is some data');
});
server.listen(3000, () => {
console.log("server.io server is listing to port 3000")
});
You must define app first. With express you can do the following:
const express = require('express');
var app = express();
Related
I have a problem using socket.io, when I do an io.on it doesn't pass the parameter. When the parameter arrives at the client, it comes undefined.
in node, when I send io.to(${room}).emit("number", JSON.parse('{"number":"1"}'))
the value passed is undefined, even passing a set value
server node:
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const cors = require('cors');
const io = require('socket.io')(server, {
cors: {
origin: '*',
}
});
users = []
app.get('/', (req, res) => {
res.send('<h1>Hello world</h1>');
});
server.listen(3000, () => {
console.log('listening on *:3000');
io.on('connection', (socket) => {
console.log('a user connected');
socket.on('conexao', (data)=>{
console.log(data)
})
socket.on('joinRoom', data=>{
console.log(data)
const userInRoom = users.find(user=> user.username === data.name && user.room === data.room)
if(userInRoom){
userInRoom.socketId = socket.id
}else{
users.push({
socketId: socket.id,
username: data.name,
room: data.room
})
}
socket.join(data.room)
console.log("sala criada")
})
socket.on("room", (room)=>{
io.to(`${room}`).emit("number", JSON.parse('{"number":"1"}'))
})
socket.on('disconnect', () => {
console.log('user disconnected');
});
});
io.attach(server)
});
```
here I am passing a number informing what the room is and I want to receive a parameter to test if the room is working. to get to this page the user has already entered the room angular typescript that makes the call:
```
import { SocketService } from './../../services/socket.service';
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-room',
templateUrl: './room.component.html',
styleUrls: ['./room.component.scss']
})
export class RoomComponent implements OnInit {
roomNumber:string = ''
constructor(private socket:SocketService){
}
ngOnInit(): void {
this.socket.on('number', (numero:JSON) =>{
console.log(numero)
const obj = JSON.parse(numero.toString())
console.log("test")
this.roomNumber = obj.number
})
}
emit(){
this.socket.emit('room', 123456 )
}
}
```
appmodule:
```
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { SocketIoModule, SocketIoConfig } from 'ngx-socket-io';
import { HeaderComponent } from './templates/header/header.component';
import { FooterComponent } from './templates/footer/footer.component';
import { HomeComponent } from './components/home/home.component';
import { RulesComponent } from './components/rules/rules.component';
import { RoomComponent } from './components/room/room.component';
const config: SocketIoConfig = {url:'http://localhost:3000'}
#NgModule({
declarations: [
AppComponent,
HeaderComponent,
FooterComponent,
HomeComponent,
RulesComponent,
RoomComponent
],
imports: [
BrowserModule,
AppRoutingModule,
SocketIoModule.forRoot(config)
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
```
The code is simple because I'm just testing the communication to continue the project.
erro: ERROR TypeError: Cannot read properties of undefined (reading 'toString')
at room.component.ts:18:37
at SocketService.on (socket.service.ts:16:31)
at RoomComponent.ngOnInit (room.component.ts:16:17)
at callHook (core.mjs:2488:22)
at callHooks (core.mjs:2457:17)
at executeInitAndCheckHooks (core.mjs:2408:9)
at refreshView (core.mjs:10434:21)
at refreshEmbeddedViews (core.mjs:11434:17)
at refreshView (core.mjs:10443:9)
at refreshComponent (core.mjs:11480:13)
I'm sending a call to the socket passing the room number and it should pass me a number back. instead it passes undefined. I've tried passing number, string and JSON and nothing worked. detail that the room is being created, as the error only happens if I am in the room "123456"
I am trying to connect a secure websocket connection from client (angular app) with my server (nodejs). I used mkcert to generate my key and cert and server is running in https showing connection is secure. when I am trying to connect with WS, the webscoet connects with server but when I use WSS I am getting an error of WebSocket connection to 'wss://localhost:port/' failed. Can anyone let me know where am I getting wrong to connect wss or how to connect wss websocket connection here?
My client side code is
app.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(){
connectToServer();
}
title = 'SSL-WEB-SOCKET-CLIENT';
}
function connectToServer() {
let ws= new WebSocket("wss://localhost:8082/");
ws.addEventListener("open", ()=>{
console.log("We are connected");
ws.send("hey, I am Client. Nice to meet you!");
});
ws.addEventListener("error", (event)=> {
console.log('WebSocket error: ', event);
});
ws.addEventListener("message", ({data})=>{
console.log("Server sent us: "+data);
});
}
Server side code
main.ts
import { NestFactory } from '#nestjs/core';
import { AppModule } from './app.module';
import * as fs from 'fs';
async function bootstrap() {
const httpsOptions = {
key: fs.readFileSync('./localhost-key.pem'),
cert: fs.readFileSync('./localhost.pem'),
rejectUnauthorized: false,
};
const app = await NestFactory.create(AppModule, {
httpsOptions,
});
await app.listen(8090);
console.log('Server started at 8090');
}
bootstrap();
app.controller.ts
import { Controller, Get } from '#nestjs/common';
import { AppService } from './app.service';
#Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
#Get()
getSecureWssConn(): string {
return this.appService.getSecureWssConn();
}
}
app.service.ts
import { Injectable } from '#nestjs/common';
#Injectable()
export class AppService {
getSecureWssConn(): string {
// eslint-disable-next-line #typescript-eslint/no-var-requires
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8082 });
wss.on('connection', (ws) => {
console.log('New Client connected');
ws.on('message', (data) => {
console.log(`Client has sent us: ${data}`);
ws.send('Hello! I am Server. Nice to meet you.');
});
ws.on('close', () => {
console.log('Client Disconnected');
});
});
return 'Hello, I am your SERVER';
}
}
Server running in browser!
I'm writing a chat app and I'm using a Node server and socket.io server side and Angular and socket.io-client client side. Unfortunately I get a "this.socketService.getMessage(...).subscribe is not a function" error when I run it. Everything else seems to work.
app.component.ts:
import { Component, OnInit, OnDestroy } from '#angular/core';
import { SocketService } from './socket.service';
import { Observable } from 'rxjs';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'chat';
registered = false;
username: string;
constructor(public socketService: SocketService) {
}
ngOnInit(): void {
this.socketService
.getMessage()
.subscribe(msg => {
if (msg === 'Registered') {
this.registered = true;
console.log(this.registered)
}
});
}
register(username: string): void {
console.log(username)
this.username = username;
this.socketService.sendMessage('register', username);
}
send(message: string): void {
this.socketService.sendMessage('message', message);
}
}
socket.service.ts:
import { Injectable } from '#angular/core';
import { io } from 'socket.io-client';
import { Observable } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class SocketService {
socket;
constructor() {
this.socket = io('http://localhost:3000/');
}
getMessage(): Observable<any> {
return this.socket.on('message', msg => {
console.log(msg);
});
}
sendMessage(type: string, words: any): void {
console.log(type, words);
this.socket.emit(type, words);
}
}
this.socket.on doesn't returns an Observable so you can't .subscribe() as you would do with an observable.
It returns a Socket as described into the docs : https://socket.io/docs/v3/client-api/#socket-on-eventName-callback
My Angular HTTP GET Request indside clearNotifications() in notification.service.ts not hitting Express Route routes/notifications.js. I am calling clearNotifications() from a component called app.component.ts. I am using Angular 7+
routes/notifications.js
const router = require('express').Router();
//Additional modules
// const db = require('../config/database');
// const notificationModel = require('../models/notifications');
//Test connection
// db.authenticate().then(() => {
// console.log('Connection has been established successfully.');
// }).catch(err => {
// console.error('Unable to connect to the database:', err);
// });
//Clear all notifications
router.get('/clear', (req, res, next) => {
console.log('clear');
// notificationModel.destroy({});
});
module.exports = router;
notification.service.ts
import { Injectable } from '#angular/core';
import * as io from 'socket.io-client';
import { Observable } from 'rxjs';
import { HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class NotificationService {
uri = 'http://localhost:5000';
private socket = io(this.uri);
constructor(private http: HttpClient) { }
getNotification() {
let observable = new Observable<{ string: String, number: String }>(observer => {
this.socket.on('notification', (data) => {
observer.next(data);
});
// return () => { this.socket.disconnect(); }
})
return observable;
}
clearNotifications() {
return this.http.get(`${this.uri}/notifications/clear`);
}
}
app.component.ts
import { Component } from '#angular/core';
import { NotificationService } from './notification.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [NotificationService]
})
export class AppComponent {
title = 'client';
string: String;
number: String;
notificationArray: Array<{ string: String, number: String }> = [];
constructor(private notificationService: NotificationService) {
this.notificationService.getNotification().subscribe(data => {
this.notificationArray.push(data);
});
}
clearNotifications() {
this.notificationArray = [];
this.notificationService.clearNotifications();
}
}
You should be doing this: Check the basic routing on express
var express = require('express');
var app = express();
app.get('/clear', (req, res) => {
console.log('clear');
res.send(success);
// notificationModel.destroy({});
});
Also make sure to subscribe to the service method from your component. If you do not subscribe the observables won't execute.
Where are you calling clearNotifications from?
subscribe to clearNotifications in component and this will work:
this.notificationService.clearNotifications().subscribe( (data) => { ..})
As a publisher, you create an Observable instance that defines a subscriber function. This is the function that is executed when a consumer calls the subscribe() method. The subscriber function defines how to obtain or generate values or messages to be published
In angular, http request returns observable, so you need to subscribe. If there aren't any subscriber to the observable, it wont be executed. Try
clearNotifications() {
return this.http.get(`${this.uri}/notifications/clear`)
.subscribe(data => //your callback function,
error => // your error handler,
complete => // any after completion task);
}
Clientside I used Angular 6 and Serverside i used node.js.
Here in angular 6 console it print message and
socket.io id({message: "Hello World", id: "6An-ctwlwbZZWrfMAAAB"})
after using below code.
this code is right or any change in this code bcoz I am not sure about this code kindly help to make correct this.
and another query is I have more than 15 components in my project so how to make common use this socket.io for all components or I have to import this app.component.ts code in all another component.
app.js(serverside)
after installing (npm i socket.io)
const express = require('express');
var app = express();
const http = require('http');
const socketIo = require('socket.io');
const server = http.Server(app);
const io = socketIo(server);
server.listen(3000,function(req,res){
console.log("listen at 3000!");
});
io.on('connection',(socket) => {
socket.emit('hello',{
message : 'Hello World',id: socket.id
})
});
app.component.ts(clientside)
after installing (npm i socket.io)
import * as socketIo from 'socket.io-client';
export class AppComponent implements OnInit {
ngOnInit(){
const socket = socketIo('http://localhost:3000/');
socket.on('hello',(data) => console.log(data));
}
}
}
The one way to achieve this mechanism is using ngx-socket-io, connect your node server at the module level or root level i have implemented like below
app.module.ts code
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { SocketIoModule, SocketIoConfig } from 'ngx-socket-io';
import { AppComponent } from './app.component';
const config: SocketIoConfig = { url: 'http://192.168.1.187:9301', options: {} };
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
SocketIoModule.forRoot(config),
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
create one service which handles your incoming and outgoing traffic.
import { Injectable } from '#angular/core';
import { Socket } from 'ngx-socket-io';
#Injectable({
providedIn: 'root'
})
export class SocketService {
constructor(public socket: Socket) { }
getMessage() {
return this.socket
.fromEvent<any>('msg')
.map(data => data.msg);
}
sendMessage(msg: string) {
this.socket.emit('msg', msg);
}
}
Update your code in your component file
export class AppComponent implements OnInit {
constructor(private socketService: SocketService) {}
title = 'app';
incomingmsg = [];
msg = 'First Protocol';
ngOnInit() {
this.socketService
.getMessage()
.subscribe(msg => {
console.log('Incoming msg', msg);
});
this.sendMsg(this.msg);
}
sendMsg(msg) {
console.log('sdsd', msg);
this.socketService.sendMessage(msg);
}
}
Create Service and turn your socket data into Observable stream
import { Injectable } from '#angular/core';
import { BehaviorSubject } from 'rxjs/behaviorSubject';
import { Observer } from 'rxjs/Observer';
import { Observable } from 'rxjs/Observable';
import * as Rx from 'rxjs';
import * as io from 'socket.io-client';
#Injectable()
export class ChatService {
observable: Observable<string>;
socket;
constructor() {
this.socket = io('http://localhost:3000');
}
getData(): Observable<string> {
return this.observable = new Observable((observer) =>
this.socket.on('hello', (data) => observer.next(data))
);
}
// This one is for send data from angular to node
pushData(e) {
this.socket.emit('hello', e);
}
}
Then Call from component
App.component.ts
import { Component } from '#angular/core';
import { ChatService } from './common/chat.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title;
chat;
constructor(private cService: ChatService) {
this.cService.getData().subscribe(data => console.log(data));
}
onClick(e: string) {
this.cService.pushData(e);
this.chat = '';
}
}
You can create a service for working with a socket. E.g (of course this is a very simple example):
/* e.g app/shared/io/io.service.ts */
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs/Observable';
import * as socketIo from 'socket.io-client';
const SERVER_URL = '/';
/** Your events enum */
export enum IOEventName {
EVENT_NAME_1 = "EVENT_NAME_1",
EVENT_NAME_2 = "EVENT_NAME_2",
...
}
/** Interfaces for your event messages */
export interface IEventName1Message {
propOne: number,
propTwo: string,
...
}
export interface IEventName2Message {
propOne: Date,
propTwo: Boolean,
...
}
...
#Injectable()
export class SocketService {
private socket: SocketIOClient.Socket;
public initSocket(): void {
this.socket = socketIo(SERVER_URL);
}
public onEvent<T>(event: IOEventName): Observable<T | Array<T>> {
return new Observable<T>(observer => {
this.socket.on(event, (data: T) => observer.next(data));
});
}
public destroy() {
if (this.socket) {
this.socket.removeAllListeners();
this.socket.close();
this.socket = undefined;
}
}
}
And use it in any components:
import { SocketService, IOEventName, IEventName1Message, IEventName2Message }
from 'app/shared/io/io.service';
export class AppComponent implements OnInit, OnDestroy {
constructor(private socketService: SocketService) { }
ngOnInit() {
this.socketService.initSocket();
this.socketService
.onEvent<IEventName1Message>(IOEventName.EVENT_NAME_1)
.subscribe(data => { /* message received */ });
this.socketService
.onEvent<IEventName2Message>(IOEventName.EVENT_NAME_2)
.subscribe(data => { /* message received */ });
}
ngOnDestroy() {
this.socketService.destroy();
}
}