简体   繁体   English

"Socket.IO 中的跨域连接"

[英]Cross-domain connection in Socket.IO

Is it possible to use Socket.IO in a cross domain manner?是否可以跨域方式使用 Socket.IO? If so, how?如果是这样,怎么做? The possibility is mentioned around the web but no code examples are given anywhere.网络上提到了这种可能性,但在任何地方都没有给出代码示例。

Quoting the socket.io FAQ : 引用socket.io FAQ

Does Socket.IO support cross-domain connections? Socket.IO是否支持跨域连接?

Absolutely, on every browser! 绝对是,在每个浏览器上!

As to how it does it: Native WebSockets are cross-domain by design, socket.io serves a flash policy file for cross-domain flash communication, XHR2 can use CORS, and finally you can always use JSONP. 至于它是如何做到的:Native WebSockets是跨域设计的,socket.io提供用于跨域flash通信的flash策略文件,XHR2可以使用CORS,最后你总是可以使用JSONP。

**Socket.IO version --> 1.3.7 ** ** Socket.IO版本 - > 1.3.7 **

Is it possible to use Socket.Io in a cross domain manner? 是否可以以跨域方式使用Socket.Io? Yes, absolutely. 是的,一点没错。

If so, how? 如果是这样,怎么样?

Option 1: Force use of Websockets only 选项1:仅强制使用Websockets

By default, websockets are cross domain. 默认情况下,websockets是跨域的。 If you force Socket.io to only use that as means to connect client and server, you are good to go. 如果强制Socket.io仅将其用作连接客户端和服务器的方法,那么你就可以了。

Server side 服务器端

//HTTP Server 
var server = require('http').createServer(app).listen(8888);
var io = require('socket.io').listen(server);

//Allow Cross Domain Requests
io.set('transports', [ 'websocket' ]);

Client side 客户端

var connectionOptions =  {
            "force new connection" : true,
            "reconnectionAttempts": "Infinity", //avoid having user reconnect manually in order to prevent dead clients after a server restart
            "timeout" : 10000, //before connect_error and connect_timeout are emitted.
            "transports" : ["websocket"]
        };

 var socket = io("ur-node-server-domain", connectionOptions);

That's it. 而已。 Problem? 问题? Won't work on browsers (for clients) who don't support websockets. 不适用于不支持websockets的浏览器(适用于客户端)。 With this you pretty much kill the magic that is Socket.io, since it gradually starts off with long polling to later upgrade to websockets (if client supports it.) 有了这个你几乎杀死了Socket.io的魔力,因为它逐渐开始长时间轮询以后升级到websockets(如果客户端支持它。)

If you are 100% sure all your clients will access with HTML5 compliant browsers, then you are good to go. 如果您100%确定所有客户都可以使用符合HTML5标准的浏览器访问,那么您很高兴。

Option 2: Allow CORS on server side, let Socket.io handle whether to use websockets or long polling. 选项2:在服务器端允许CORS,让Socket.io处理是否使用websockets或长轮询。

For this case, you only need to adjust server side setup. 对于这种情况,您只需要调整服务器端设置。 The client connection is same as always. 客户端连接与以前一样。

Server side 服务器端

//HTTP Server 
var express=require('express');
//Express instance
var app = express();

//ENABLE CORS
app.all('/', function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  next();
 });

That's it. 而已。 Hope it helps anyone else. 希望它可以帮助其他人。

只需在创建客户端套接字时插入远程域名:

var socket = io.connect('http://example.com:8080');

Socket.io supports cross-domain connections, but keep in mind that your cookie will not be passed to the server. Socket.io支持跨域连接,但请记住,您的cookie不会传递给服务器。 You'll have to either: 你必须要么:

(1) come up with an alternate identification scheme (a custom token or a javascript cookie-- just keep in mind this should not be the actually session id, unless you want to put yourself at risk of session hijacking) (1)提出备用识别方案(自定义令牌或javascript cookie) - 请记住,这不应该是实际的会话ID,除非你想让自己面临会话劫持的风险)

or (2) send a good old fashioned HTTP JSONP request to the server first to get the cookie. 或者(2)首先向服务器发送一个好的旧式HTTP JSONP请求以获取cookie。 Then it will be transmitted w/ the socket connection handshake. 然后它将通过套接字连接握手传输。

Easy and security! 简单安全!

In the main file place it before io.on('connection'), add the lines: 在主文件中将它放在io.on('connection')之前,添加以下行:

io.set('origins', 'yoursite.com:*');

io.on('connection', function (socket) {

Yes it does. 是的,它确实。 I have implemented cross domain socket.io to test whether it works. 我已经实现了跨域socket.io来测试它是否有效。

<script src="http://your-nodejs-domain.com:3000/public/js/jquery.js"></script>
  <script src="http://your-nodejs-domain.com:3000/socket.io/socket.io.js"></script>
  <script>

      var socket = io.connect('http://your-nodejs-domain:3000');
      $(document).ready(function(){

          socket.on('test message', function(msg){
               console.log("Got the message: " + msg);
          });
      });

  </script>

That should work fine. 这应该工作正常。

create your server by io like this: 通过io创建您的服务器,如下所示:

const server = require('http').createServer();

const io = require('socket.io')(server, {
    origins:["127.0.0.1:8000"],
    path: '/',
    serveClient: false,
    // below are engine.IO options
    pingInterval: 20000,
    pingTimeout: 5000,
    cookie: false
});

io.on('connection', function(socket){
    console.log("here new user welcom")
});


server.listen(3000,function(){
    console.log('listening on *:3000')});

in the origins array specify valid origin 在originins数组中指定有效的原点

As of v4, according to the docs :从 v4 开始,根据文档

Since Socket.IO v3, you need to explicitly enable Cross-Origin Resource Sharing (CORS).从 Socket.IO v3 开始,您需要显式启用跨域资源共享(CORS)。

You can use the cors key in the configuration object passed to new Server() .您可以在传递给new Server()的配置对象中使用cors键。 See this basic example from the above docs page :请参阅上述文档页面中的这个基本示例

import { createServer } from "http";
import { Server } from "socket.io";

const httpServer = createServer();
const io = new Server(httpServer, {
  cors: {
    origin: "https://example.com"
  }
});

origin can be an array to accept multiple origins. origin可以是一个接受多个来源的数组。

Other options include allowRequest , allowedHeaders , withCredentials , extraHeaders and others from the cors package which ultimately handles the CORS headers under the hood.其他选项包括allowRequestallowedHeaderswithCredentialsextraHeaderscors包中的其他选项,它们最终在后台处理 CORS 标头。

I also tested slightly different syntax than this answer , which worked for me with 4.4.1:我还测试了与这个答案稍有不同的语法,这对我来说适用于 4.4.1:

const express = require("express");
const app = express();
const server = require("http").createServer(app);
const io = require("socket.io")(server, {
  cors: {origin: ["https://glitch.me", "https://cdpn.io"]}
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM