I'm building news app.
I created reusable component for my news in which I am displaying them one by one.
I'm trying to connect to the socket.io server by id of the current article but it is not working.
Here is how I'm trying to achieve it.
useEffect(() => {
const socket = socketIoClient(URL, {
transports: ['websocket'],
jsonp: false,
});
socket.connect();
socket.on(`connect${currentPost.id}`, () => {
console.log('connected to socket server');
});
}, [currentPost.id]);
URL is link of heroku
It is connecting to the server if I only write 'connect' without currentPost.id and I don't understand why.
I'm using react native version:0.63.3
And socket.io-client": "^2.1.1"
Any suggestions please?
The way you have it set up right now is that on every currentPost change you try to connect the socket again, although the connection should already be established.
Moreover, you are waiting for an event on the socket which I'm afraid does not really exist (although that depends on how serverside socket communicates with your frontend). It works for just plain socket.on('connect'...) because it's what socket understands.
If you make clearer what exactly you want to achieve, I may try to provide additional help, for now I'm not sure about your final goal and how you diverge from it.
Related
I am using PouchDB and CouchDB in an ionic application. While I can successfully sync local and remote databases on Chrome and Android, I get unauthorized error on Safari / iOS when I run the sync command. Below is a simplified version of my database service provider.
import PouchDB from 'pouchdb';
import PouchDBAuthentication from 'pouchdb-authentication';
#Injectable()
export class CouchDbServiceProvider {
private db: any;
private remote: any;
constructor() {
PouchDB.plugin(PouchDBAuthentication);
this.db = new PouchDB('localdb', {skip_setup: true});
}
...
login(credentials) {
let couchDBurl = 'URL of my couchDB database';
this.remote = new PouchDB(couchDBurl);
this.remote.logIn(credentials.username, credentials.password, function (err, response) {
if (err) { concole.log('login error') }
else {
let options = { live: true, retry: true, continuous: true };
this.db.sync(this.remote, options).on('error', (err_) => { console.log('sync error')});
}
})
}
...
}
In the code above, this.remote.logIn(...) is successful but this.db.sync(...) fails. I have checked the requests via the network tab of developer tools and I believe the issue is that the cookie that's retruned in the response header of this.remote.logIn(...) is not used by the subsequent calls (thus the unauthorized error). The issue is fixed once third-party cookies are enabled on Safari, which is not an option on iOS.
How can I fix this problem?
One potential solution I'm considering is overriding fetch to use native http client (i.e., an instance of HTTP from #ionic-native/http). It seems modifying http clients is a possibility (e.g., according to this conversation) but I'm not sure how to achieve that.
Changing the HTTP plumbing sounds like a really bad idea - time cost, mainly - unless you just absolutely have to use sessions/cookies...If you don't, read on.
as noted here regarding pouchDB Security, I tried using pouchdb-authentication when it was actively maintained and went another route due to multiple issues (I don't recall specifics, it was 6 years ago).
Do note the last commit to pouchdb-authentication seems to be 3 years ago. Although inactivity is not an negative indicator on the surface - a project may have simply reached a solid conclusion - installing pouchdb-authentication yields this
found 6 vulnerabilities (2 moderate, 3 high, 1 critical)
That plus the lack of love given to plugin over the last few years makes for a dangerous technical debt to add for a new project.
If possible simply send credentials using the auth option when creating (or opening) a remote database, e.g.
const credentials = { username: 'foo', passwd: 'bar' };
this.remote = new PouchDB(couchDBurl, { auth: credentials });
I don't recall why but I wrote code that is in essence what follows below, and have reused it ad nauseum because it just works with the fetch option
const user = { name: 'foo', pass: 'bar' };
const options = { fetch: function (url, opts) {
opts.headers.set('Authorization', 'Basic ' + window.btoa(user.name+':'+user.pass));
return PouchDB.fetch(url, opts);
}
};
this.remote = new PouchDB(couchDBurl, options);
I believe I chose this approach due to the nature of my authentication workflow discussed in the first link of this answer.
I agree with #RamblinRose that you might have to include the headers manually when you define the PouchDB object.
I myself have found a solution when working with JWTs that need to be included in the header for sync purposes.
See this answer. Note: RxDB uses PouchDB under the hood so it's applicable to this situation. It helped me sync, hope it does you too!
https://stackoverflow.com/a/64503760/5012227
One potential solution I'm considering is overriding fetch to use native http client (i.e., an instance of HTTP from #ionic-native/http). It seems modifying http clients is a possibility (e.g., according to this conversation) but I'm not sure how to achieve that.
Yes, this is a possible option - especially if you want to use SSL pinning which will only work with native requests. And you don't need to worry about CORS (apart from ionic serve).
You can achieve this e.g. by taking an existing fetch - polyfill and modifying it s.t. it uses the http plugin instead of xhr. And since you'll only deal with JSON when interacting with the CouchDB, you can throw away most of the polyfill.
How can I listen the changes occurred in the Gun server database :
My server is listening like below
var Gun = require('gun');
var server = http.createServer();
var gun = Gun({web: server});
server.listen(port, function () {
console.log('Server listening on ...')
})
While puting the data from Gun client my data.json file updated. Now I need to get the listern the whole changes happening in the db. I think on a perticuler node I can listern using gun.on method. Can we able to Listern the whole changes/ change request coming from the client?
#ajmal-m-a yes, via the "wire spec" (you'll need to understand the graph format, here is a tech talk where I explain it in 30min on stage):
gun.on('in', function(msg){}) where gun is the root.
Note: You'll need to understand how to handle the middleware event hook system - your listener will need to remember to call this.to.next(msg).
A good and simple resource to look at is this:
https://github.com/zrrrzzt/bullet-catcher
Does this help?
(Sorry for the delay in answering the question, we were headed into a conference at that time, and it got buried under a bunch of emails)
I have this use case:
- I'm working on a game with a webapp for user management and chat, which is on MERN, and a unity game, with socket.io as the real time messaging layer for the multiplayer game.
- User may register to webapp by either providing a pair of email/password, or getting authenticated on FB/Gamil/etc. as usual, in which case the user's email is obtained and saved to MongoDB and this is done by passport.
- There is no session in express side, and socket.io is on a redis. There is no cookie but JWT is used.
My problem is that I don't know what's the best practices in this. I read this
article
and this
one
which both have content and code close to what I want to do, but in the first one:
app.use(express.cookieParser());
while I don't want to use cookie at all, and the other one also has in code:
cookie: {
secure: process.env.ENVIRONMENT !== 'development' && process.env.ENVIRONMENT !== 'test',maxAge: 2419200000}...
Also, I found this on
github
which suggests for the client side (unity):
var socket = io.connect('http://localhost:9000');
socket.on('connect', function (socket) {
socket.on('authenticated', function () {
//do other things
})
.emit('authenticate', {token: jwt}); //send the jwt
});
meaning that:
1. socket is created
2. authentication is requested
but I think that the approach I found in the other article is better, where the socket is not created at all if the JWT for auth is not provided at the first ever connection request sent to "io", so if I'd do it I'd issue:
var socket = io.connect('http://localhost:9000', {query: {"JWT":"myjwt"}});
and in my server side where I have:
io.on("connection", function(socket){...});
I'd like to first get the JWT:
var jwt = socket.handshake.query["JWT"];
and then if auth will be unsuccessful, simply return socket.disconnect('reason') and do not open any connection at all (here maybe I just didn't understand, say, that the approach the Author took in the github source is using a middle ware technique and it is maybe also done before anything else).
I still could not find out what is the best practice that Gurus use, please help me get clear.
I have a React App that uses React Router and Redux as its state manager. The server side of the app uses Express and Node.
I am making API calls to an external service. I do not have the ability to enable CORS on the external service. Therefore, I need to use my app's server side to make the calls to the external service to remove the browser from the equation, and eliminate any CORS error.
I am able to get my data from the service on the server side successfully. I would like to know if it is possible to share the Redux store in between the client and server with some sort of middleware (looking for examples/resources).
The goal:
1) Handle a click event in the client
2) Have that event call a server side route to external api (don't know how to do this)
3) Then the server handles this route, makes the request, and sends the response to the client (through the shared react store - not sure if this is possible)
4) The store gets the new state, and then sends to the client side components, and the UI updates
Are there any examples/tutorials of this? Not looking for an initial server rendered page, but guides that inform how the above 4 steps can generally be implemented.
Thanks for the suggestions.
It turns out that I was severely over thinking the solution. All I really needed was the ability to launch a server side function (get resources from external API) from the client side event (load component). Sort of like how submitting a form, has an action that launches a server side function.
In my component:
componentDidMount() {
const product_api_results = productApi.getProductItems()
console.log('product_api_results in CART Component: ', product_api_results)
/* now I have results and can put it in the Redux Store via action to reducer for other components to work with on client */
}
The productAPI.getProductItems() that the component calls:
export function getProductItems () {
return axios.get('/api/get-products') // triggers a server side route
.then(function (response) {
console.log('client side response: ', response)
return response
})
}
In Express server.js file, the server will see this url and then get the proper data. The shopify.get() is from the shopify-node-api module:
app.get('/api/get-products', function (req, res) { // '/api/get-products' called from client
shopify.get('/admin/products.json', function (err, data, headers) {
res.send(data)
})
})
This question may sound lame but.
Is there any technique to send push notificaiton from server to client side, regarding the server status.
For Example:
While Login
Notification in Client Side in sequence:
Validating User ...
Validating Digital Certificate ...
Sorting downloadable file ...
Preparing to download ...
If its not possible, then is there any alternative elegant way to achieve this.
Thanks
You can use SignalR :
$.connection.hub.start().done(function () {
$('#sendmessage').click(function () {
// Call the Send method on the hub.
chat.server.send($('#displayname').val(), $('#message').val());
// Clear text box and reset focus for next comment.
$('#message').val('').focus();
});
});
use more info: tutorial
you can use signalR here i am providing link have a look on it.
http://www.asp.net/signalr