i18n-node icon indicating copy to clipboard operation
i18n-node copied to clipboard

i18n and socket.io

Open xfg opened this issue 9 years ago • 9 comments

How to use i18n and socket.io ? Every socket must have own language.

I tried do so:

io.use(i18n.init);

io.use(function (socket, next) { var lang = socket.request._query.lang; ... socket.setLocale(lang); next(); });

but it didn't work, I get the current error:

../node_modules/i18n/i18n.js:325 var language_header = request.headers['accept-language'], ^ TypeError: Cannot read property 'accept-language' of undefined

Are whether preferred way solve it ? Thanks.

xfg avatar Mar 12 '15 16:03 xfg

i18n.init is intended to be used as http middleware. In case of socket.io there won't exist any request.header I guess? So you will need to mimic the init by yourself. It would be interesting to find a solid integration with socket.io. Are there any best practices for handling language settings via sockets out there?

mashpie avatar Mar 16 '15 16:03 mashpie

fyi: I started working on a socket.io example last week

mashpie avatar Jan 31 '16 19:01 mashpie

Would love to see this feature. As long as I can see it's so modular that the real problem seems to be only the init function?

fourpixels avatar Feb 29 '16 09:02 fourpixels

this seems to work:

const app = express()
const http = require('http').Server(app)
const io = require('socket.io')(http)

i18n.configure({
  locales: ['en', 'de'],
  directory: `${__dirname}/locales`
})

app.use(i18n.init)

io.on('connection', (socket) => {
  const req = socket.request
  i18n.init(req)
  // req.setLocale('de') // if override required
  socket.emit('message', req.__('Hello'))
})

http.listen(3000)

With it initialized on the socket, any time you have the socket object, __ will be there for translation. Also, socket.request is a regular request, so it has headers['accept-language'] and potentially cookies if a parser is available - so the language inference in guessLanguage should still work.

tswaters avatar Mar 27 '16 22:03 tswaters

:+1: well done - implemented as intended with i18n.init inside connection callback. So i18n binds to both express + socket.io. Keep in mind that express.req won't share any state with socket.request...

mashpie avatar Mar 29 '16 13:03 mashpie

Wow! It's cool, guys. :+1:

xfg avatar Apr 07 '16 18:04 xfg

btw. anyone tried with .use()? http://socket.io/docs/server-api/#namespace#use(fn:function):namespace

var io = require('socket.io')();
io.use(function(socket, next){
  i18n.init(socket.request);
  next();
});

mashpie avatar Apr 08 '16 20:04 mashpie

@xfg who posted the question said he can't do it, because of accept-language header not being found, but as far as I can see he's not initializing it with socket.request.

Anyways, would be nice to not always look for that header (please see my other bug posted here)

fourpixels avatar Apr 08 '16 21:04 fourpixels

hm concerning your #216: i18n returns from guessing before testing for headers when you configure any other options, like query param or cookie name. see https://github.com/mashpie/i18n-node/blob/master/i18n.js#L666

this effectively quits using any headers... I admit to not have read the whole #216 yet - so I might muss some details :)

mashpie avatar Apr 08 '16 21:04 mashpie