Postman wont connect to Nestjs websocket - websocket

I am trying to connect to my Nestjs websocket with postman for rapid testing during development but I am having a lot of trouble getting postman to actually connect.
This is my errror
Error: connect ECONNREFUSED 127.0.0.1:8000
Here is my server code:
import { Logger } from '#nestjs/common';
import { OnGatewayConnection, OnGatewayInit, SubscribeMessage, WebSocketGateway } from '#nestjs/websockets';
#WebSocketGateway({ namespace: "test", cors: true })
export class AppGateway implements OnGatewayInit, OnGatewayConnection {
private logger: Logger
constructor() {
this.logger = new Logger('AppGateway')
}
afterInit(server: any) {
this.logger.log("Gateway is running")
}
handleConnection(client: any, ...args: any[]) {
this.logger.log("Client Connected")
}
#SubscribeMessage('message')
handleMessage(client: any, payload: any): string {
return 'Hello world!';
}
}
This is extremely simplistic because I actually spun up a new nestjs server incase it was something to do with authentication
Here is a picture of my postman UI to show what I am doing there (I am using socket-io v4 on my server which is why I have that option selected on postman)
I have also tried the url ws://127.0.0.1:8000/test but this produces the same error (also have tried using localhost instead of 127.0.0.1)
I know my websocket server is functioning correctly (and on the correct port) because I spun up a quick react app using the socketio client library and it connected to the websocket fine.
Here is the code to my quick react app:
import logo from './logo.svg';
import './App.css';
import { io } from 'socket.io-client'
function App() {
const socket = io("http://localhost:8000/test")
console.log(socket)
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
I have been stuck on this for a day or two now so any help would be great!
Thanks in advance.

I had a similar problem when running NestJS in WSL and trying to connect via Postman.
As far as I understood, there is a bug report that, when using socket.io feature, Postman attempts to convert localhost to 127.0.0.1 which does not work because it's not the WSL IP.
So, in order to make it work you need:
Open a PowerShell to get WSL IP (it changes every time WSL reboots):
wsl hostname -I
Use the output IP to connect via Postman:
http://<ip>:8000/test
About http or ws, using socket.io, it doesn't matter if you choose http or ws to connect, socket.io docs tells us the following
You can use either https or wss (respectively, http or ws).

Related

Listen to XRPL payments: Google Cloud Run container failed to start and listen to the port

I have an XRP wallet and I'm trying to monitor incoming payments to this address with WebSockets.
My code works fine locally.
After I subscribed to the wallet address, I simply listen to "transaction" events and get the details about the payments made to that address.
But, I need it to run 24/7 on the cloud. Nothing heavy is here. It is simply a single connection running forever.
The problem is, when I deploy my code to Google Cloud Run, I get the following error:
The user-provided container failed to start and listen on the port defined provided by the PORT=8080 environment variable.
So here is my question:
Given that I'm listening to "transactions" via wss://xrplcluster.com/ (with no ports), how should I modify my code to resolve the Cloud Run complain.
Here you are my code and thanks in advance.
import { Client } from 'xrpl';
const client = new Client("wss://xrplcluster.com/");
async function main() {
await client.connect();
const response = await client.request({
command: "subscribe",
accounts: ["my-wallet-address"]
})
client.on("transaction", tx => {
if (tx.validated) {
const transaction = {
amount: tx.transaction.Amount,
from: tx.transaction.Account,
};
console.log(transaction);
}
});
client.on("disconnected", async code => {
console.log(`The wss client is disconnected with code: ${code}`);
await client.connect();
});
}
main();

NextJS - how to configure proxy to log api requests and responses?

I am having an issue with the Cloudinary Node SDK where the Admin Resources endpoint is occasionally throwing a 302 error. Their support suggested that I proxy the request so that I can log the response between my api and their SDK and ultimately get a better idea of what might be causing the problem (in the end they're hoping to see the Location headers that are in the Response).
One of their suggestions was to use Charles Proxy, however I'm very new to how this works and am unable to figure it out. I've read through the Charles docs and spent a full day googling, but I can't find any info related to proxying between the NextJS API and Cloudinary SDK specifically.
How do I go about setting up Charles Proxy so that I can see the request and response in this way? Is there another way that I don't know of that would work instead? Since I'm using the newest version of NextJS v12, could I use the new _middleware option instead? In a later suggestion, their Support made this comment too:
if you can't proxy requests to localhost, you may be able to use a local DNS server or a local override so you can access your local IP using a different hostname (e.g. using /etc/hosts on a unix environment, or C:\Windows\System32\Drivers\etc\hosts on a windows PC) and have that proxied - that said, there's probably an easier way using a Node project or adjusting the settings of the Node server.
but I have no idea where to begin with this either.
Here is the api code I have:
pages/api/auth/images.ts
import type { NextApiRequest, NextApiResponse } from 'next';
import cloudinary from 'cloudinary';
require('dotenv').config();
export default async function handler(_: NextApiRequest, res: NextApiResponse) {
cloudinary.v2.config({
cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
api_key: process.env.CLOUDINARY_API_KEY,
api_secret: process.env.CLOUDINARY_API_SECRET,
secure: true,
});
try {
// fetch cloudinary auth images
const response = await cloudinary.v2.api.resources({
type: 'upload',
prefix: 'my_app/auth_pages',
max_results: 20,
});
// fetch random image
const randImage =
response.resources[~~(response?.resources?.length * Math.random())];
// return image
return res.status(200).json({ image: randImage });
} catch (error) {
console.dir({ error }, { colors: true, depth: null });
return res.status(500).json({ error });
}
}
Note: I'm on a Mac.
Try the following:
export default async function handler(_: NextApiRequest, res: NextApiResponse) {
cloudinary.v2.config({
cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
api_key: process.env.CLOUDINARY_API_KEY,
api_secret: process.env.CLOUDINARY_API_SECRET,
api_proxy: 'http://<local_ip>:<charles_port>', //change accordingly
secure: true,
});
To get the port number, In Charles Proxy go to Proxy > Proxy Settings.

Unable to listen to Socket IO from Laravel Server in Flutter App

I have been using Laravel as backend to create my flutter app. I am building a live chat system and it has been working on the web version in Laravel. However, I am trying to listen to the socket messages and have tried almost every packages to listen to Laravel Socket like flutter_socket_io and tried laravel_echo also but the documentation is a little misleading. There is no option to add the server link and listen to the Event. So I am confused whether I am missing something or there isn't a good package for Laravel, Socket IO and Flutter.
There is pretty good documentation at laravel_echo plugin, make sure you follow the documentation.
To use with socket.io, you need to install socket_io_client for your Flutter app.
import 'package:socket_io_client/socket_io_client.dart' as IO;
Echo echo = new Echo({
'broadcaster': 'socket.io',
'client': IO.io,
'host': 'https://example.com:6001, //url:port
'auth': {
'headers': {'Authorization': 'Bearer $token'}
}
});
echo.join('your_channel_name').here((users) {
print(users);
}).joining((user) {
print(user);
}).leaving((user) {
print(user);
}).listen('PresenceEvent', (e) {
print(e);
});
If you are using a secure server, you can use the badCertificateCallback callback of HttpClient and just return true. This will accept all the bad certificates.
class MyHttpOverrides extends HttpOverrides {
#override
HttpClient createHttpClient(SecurityContext context) {
return super.createHttpClient(context)
..badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
}
}
void main() {
HttpOverrides.global = new MyHttpOverrides();
runApp(MyApp());
}

"Must provide query string" error with Apollo Client on React and Nexus Graphql Server

I'm starting to work with GraphQL and the new Nexus Framework GraphQL server, which is a great product.
On my server-side, I defined my schema, I can query my database with Prisma and everything runs smoothly. I can query data also from the Nexus GraphQL playground and also with Postman.
Now, I want to make things work on the client-side. I see that Apollo Client is the best solution to integrate React with GraphQL, but I just can't make things work. I read tons of docs but I'm missing something that I can't figure out.
GraphQL and the client part will be hosted on the same server, on separate node applications.
I'm configuring Apollo based on its documentations. The example below is for the new 3.0 Beta Version of Apollo which I'm testing, but the same scenario happens on the last stable version. I believe that I need to do something else to integrate Apollo and Nexus.
Every query returns: "Must Provide Query String".
The same query inside the playground works perfectly.
Here is my basic testing code:
apollo.js:
import { ApolloClient, HttpLink, InMemoryCache } from '#apollo/client'
const client = new ApolloClient({
cache: new InMemoryCache(),
link: new HttpLink({
uri: 'http://localhost:4000/graphql',
fetchOptions: {
mode: 'no-cors',
}
})
})
export default client
App.js:
import React from 'react'
import { ApolloProvider } from '#apollo/client';
import client from './database/apollo'
import Home from './components/Home'
const App = () => {
return (
<ApolloProvider client={client}>
<Home />
</ApolloProvider>
)
}
export default App;
Home.js:
import React, { useState, useEffect, useReducer } from 'react'
import { useQuery, gql } from '#apollo/client'
const PUBLICATIONS = gql`
{
albumreviews(last: 1) {
title
}
}
`
const Home = () =>{
const { loading, error, data } = useQuery(PUBLICATIONS)
if (loading) return <p>Loading...</p>
if (error) return <p>Error :(</p>
return data.albumreviews.map(({ review }) => (
<div>{JSON.parse(review)}</div>
))
}
export default Home
On the client-side: "Error" is displayed.
On the server-side: "Must provide query string"
Believe me, I've tried to adjust the query thousands of times trying to get a different answer.
Could some help me to move forward with this? Should I provide the Nexus schema to the apollo client? What is the better way of doing this?
You should pretty much never use no-cors. Off hand, I'm not sure why that option would cause your request to be malformed, but it will make it impossible for your response to be read anyway. Remove fetchOptions and whitelist your client URL in your CORS configuration on the server-side. CORs usage with Nexus is shown here in the docs.

Authenticate with client certificate without CORS

I want to be able to request a distant API with my Angular 5 app.
The API server is asking a SSL-certificate in order to authenticate the client.
This certificate is distributed - by the company that provide the API - to a limited number of users, by handing them directly an USB key that contains the certificate (which is delivered by a trusted CA).
That means that I don't have access to a .pem or .crt file. Instead, the certificate is locally stored in the Windows AD (or local store) and I can't export the private key (for obvious security reason).
But the CA is also providing drivers that allow to register a certificate (if your USB key is plugged) to your favorite browser.
So I tried with the following test project:
app.component.ts
import {Component, OnInit} from '#angular/core';
import {Http, Response, RequestOptions, Headers} from '#angular/http';
import {HttpClient} from '#angular/common/http';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'TEST API';
url = 'https://myAPIurl/lgcMessagerieInbox';
result = '';
constructor(private http: HttpClient) {
}
ngOnInit(): void {
}
testAPIcall(): void {
this.http.get(this.url)
.subscribe(
data => {
console.log(data);
},
error => {
console.log(error);
}
);
}
}
app.component.html
<div class="container">
<h1>
{{ title }}
</h1>
<button class="btnStandard" type="button" (click)="testAPIcall()" >TEST</button>
<div *ngIf="result">
{{ result }}
</div>
</div>
The first good news was that the browser automatically detected the fact that the API was asking a certificate and opened a windows so I could select a certificate, enter my pin code and send the http request.
But it failed because the server doesn't accept CORS requests ( https://www.html5rocks.com/en/tutorials/cors/ ).
So I though of using the local proxy provided by Angular in order to redirect the request so the browser doesn't block it because of different domain name. But then I wasn't able to pass the certificate through the proxy.
My questions are :
Is there a way to read the certificate directly on the windows local
store from my Angular app? I'm almost certain there is not if I
trust what I've been searching on internet over the past 3 days.
How can I pass a certificate through a proxy (Angular or anything else)?
If the two options above are not available, do you know a way to access the API knowing the constraints (using an other techno but it must be
cross-platform)?

Resources