Please open an issue on our github tracker, I am not sure if we should just remove the saving to user settings in the sort dropdown all together and move the sort settings to /user/<slug>/settings like everything else. Then you can change the sort order in every topic without effecting your settings. The setting used in the user page would be the default sort when you enter a topic.
Getting a valid session for a Socket.IO app
-
With v1.0.0, Socket.IO now requires a valid session cookie. My apps no longer work since they are not in a browser and I don't know how/if I can get a valid cookie? I'm using socket.io-client-java.
-
I think I just need to set a header with the nodebb secret in it.
-
Okay! That made express add
signedCookies
to my request, but I'm not sure what cookie to send with it. The only cookie in the response isio
, and nodebb is looking forexpress.sid
. Nevermind I don't think that actually did anything. -
Hmm, I'm stuck. I have a feeling there's no way to connect to the forum using socket.io only now from my Java app. Maybe it will work if I send an initial connection via http... but this is a bit inconvenient since I only send messages to my
plugins.*
namespace. -
I'm working on a similar project in NodeJS and i came up with a fairly simple solution that involves making an HTTP request to get the session cookie and then telling the socket to use that session
demonstration code (JS)
'use strict'; const request = require('request'); const io = require('socket.io-client'); const jar = request.jar(); const forum = 'https://community.nodebb.org'; request.get({ url: forum, jar: jar }, function () { const cookies = jar.getCookieString(forum); const socket = io(forum, { extraHeaders: { 'Cookie': cookies } }); socket.on('connect', () => { console.log('connected'); socket.on('pong', (ms) => console.log('pong', ms)); socket.emit("topics.loadMore", { "tid": 8046, "after": 1, "direction": 1 }, (e, result) => console.log(result)); }); });
Assuming you're using the official socket.io-client for Java it looks like you'll be able to get at the cookies in Java a bit of a different way:
https://github.com/socketio/socket.io-client-java#transports-and-http-headers -
Thanks! Yeah, figured I would have to go this way. It's just kind of a bummer because before now I could just make requests to my socket namespace without the extra hassle.
-
@yariplus no problem,
It's a bit annoying, yes. but at least the way to do the header fiddling was actually documented for you in the Java client.
I had to trace the code to figure out that that
extraHeaders
object was even a thing for the javascript client.All I was able to find through googling was workarounds that involved monkey patching XMLHttpRequest in ways that were either extremely version specific or just didn't work.
I literally headdesked when i found out it was really as simple as adding an as yet undocumented key to the socket configuration.
-
Okay! It works perfect now that I GET the Cookie first. It was pretty easy using the OkHttp3 library, which was already a dependent of SocketIO, so I didn't have to add any more dependencies.
I'm not sure if this is useful to anyone else, but here is my test app.
package com.radiofreederp.nodebbapp; import io.socket.client.Ack; import io.socket.client.IO; import io.socket.client.Manager; import io.socket.client.Socket; import io.socket.emitter.Emitter; import io.socket.engineio.client.Transport; import okhttp3.*; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import java.net.URISyntaxException; import java.util.Arrays; import java.util.List; import java.util.Map; public class NodeBBApp { private String url; private OkHttpClient client = new OkHttpClient(); private String cookie; private Socket socket; NodeBBApp(String url) { this.url = url; } private void getCookie() throws IOException { Request request = new Request.Builder().url(url).build(); Response response = client.newCall(request).execute(); cookie = response.headers().get("Set-Cookie"); } private void connectSocket() throws URISyntaxException { socket = IO.socket(url); // Send the session cookie with requests. socket.io().on(Manager.EVENT_TRANSPORT, new Emitter.Listener() { @Override public void call(Object... args) { Transport transport = (Transport)args[0]; transport.on(Transport.EVENT_REQUEST_HEADERS, new Emitter.Listener() { @Override public void call(Object... args) { @SuppressWarnings("unchecked") Map<String, List<String>> headers = (Map<String, List<String>>)args[0]; headers.put("Cookie", Arrays.asList(cookie)); } }); } }); socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() { @Override public void call(Object... objects) { JSONObject data = new JSONObject(); try { data.put("tid", 45); data.put("after", 1); data.put("direction", 1); } catch (JSONException e) { e.printStackTrace(); } socket.emit("topics.loadMore", data, new Ack() { @Override public void call(Object... objects) { System.out.println("Response:"); if (objects.length == 2 && objects[0] == null) { JSONObject data = (JSONObject)objects[1]; try { JSONArray posts = data.getJSONArray("posts"); for (int i = 0; i < posts.length(); i++) { System.out.println(((JSONObject)posts.get(i)).get("content")); } } catch (JSONException e) { e.printStackTrace(); } } socket.close(); } }); } }); socket.connect(); } public static void main(String [] args) { NodeBBApp app = new NodeBBApp("http://www.yaricraft.com/"); try { app.getCookie(); app.connectSocket(); } catch (IOException e) { e.printStackTrace(); } catch (URISyntaxException e) { e.printStackTrace(); } } }