长连接(socket)和短连接(ajax)。
长连接不存在跨域问题。
http协议不支持长连接。

实现socket的三种方式:

  1. net,node的内置模块
  2. socket.io
    兼容性好,但是要先引入
  3. websocket
    websocket是h5新增,低版本浏览器不兼容。

长连接的使用场景:

  • 实时刷新
    如果前端使用轮询,那么前端和服务端都要耗费资源,如果使用socket长连接,那么就只需服务端发送就可以了。
  • 服务器端发起数据
    ajax是前端主动往后端发送消息,后端无法主动往前端发送消息(服务器主动推送消息)。

socket的步骤

前后端的连接
1、搭建socket服务器
2、 前端进行连接

数据交互
3、 前端主动发送数据
4、后端主动发送数据

前后端断开的处理
5、断开连接

1、net模块

服务端

const net = require('net')

const server = new net.createServer()

let clients = {}
let clientName = 0

server.on('connection', (client) => {
  client.name = ++clientName
  clients[client.name] = client

  client.on('data', (msg) => {
    // console.log('客户端传来:' + msg);
    broadcast(client, msg.toString())
  })

  client.on('error', (e) => {
    console.log('client error' + e);
    client.end()
  })

  client.on('close', (data) => {
    delete clients[client.name]
    console.log(client.name + ' 下线了');
  })
})

function broadcast(client, msg) {
  for (var key in clients) {
    clients[key].write(client.name + ' 说:' + msg)
  }
}

server.listen(9000)

前端

var net = require('net')
const readline = require('readline')

var port = 9000
var host = '127.0.0.1'

var socket = new net.Socket()

socket.setEncoding = 'UTF-8'

socket.connect(port, host, () => {
  socket.write('hello.')
})

socket.on('data', (msg) => {
  console.log(msg.toString())
  say()
})

socket.on('error', function (err) {
  console.log('error' + err);
})

socket.on('close', function () {
  console.log('connection closeed');
})

const r1 = readline.createInterface({
  input: process.stdin,
  output: process.stdout
})

function say() {
  r1.question('请输入:', (inputMsg) => {
    if (inputMsg != 'bye') {
      socket.write(inputMsg + '\n')
    } else {
      socket.destroy()
      r1.close()
    }
  })
}

2、socket.io

使用自定义的事件的监听和触发机制
先下载

npm install socket.io

服务端

var express = require('express');
var app = express();
var server = require('http').Server(app);// 通过http创建一个服务器
var ws = require('socket.io')(server);//将socket 服务器和express 进行结合,通过express启动socket.io

// 静态文件目录
app.use(express.static(__dirname + '/client'))
// 客户端连接
ws.on('connection', function (client) {
    client.emit('hehe','欢迎光临')//触发事件(触发hehe事件,在前端监听hehe事件)
    client.on('haha',(msg)=>{//绑定(监听)事件,在前端触发haha事件
      console.log('haha'+msg)
    })
});

// 允许所有端口访问
server.listen(8081, '0.0.0.0');

前端
引入socket.io

var socket = io.connect('http://localhost:8081');//连接服务器
    
socket.on('hehe', function(msg){
        console.log('hehe'+msg)
      })
socket.emit('haha','我来了')

3、websocket

先下载包

npm install ws

服务端

const WebSocket=require('ws');// 创建websocket服务器
const ws=new WebSocket.Server({port:8080},()=>{
    console.log("socket start!")
})

let clients=[];//存储每个与服务器连接的客户端,用于群发

// 与前端建立连接
ws.on('connection',(client)=>{
    // 将每个与服务器链接上的client对象push到clients数组中
    clients.push(client);
    client.send('欢迎光临hello');//数据传输只能传字符串,传对象先JSON.stringify
    client.on('message',(msg)=>{//监听message,前端发数据过来时触发
        console.log(msg);
        if(msg.indexOf("广播")!=-1){
            sendAll(msg);
        }
    })
    client.on('close',(msg)=>{
        console.log("前端主动断开了链接")
    })
})

// 群发
function sendAll(msg){
    for (let i = 0; i < clients.length; i++) {
        clients[i].send(msg);
    }
}

前端
浏览器或nw自带,不需引入

// 创建websocket服务器
    const ws=new WebSocket('ws://192.168.31.180:8080/');//服务器地址(或ws://localhost:8080/),使用的协议是ws协议

    // 监听与服务器建立连接
    ws.onopen=function(){
        console.log('服务器已经连接')
    }
    // 监听message,接收来自服务端的数据
    ws.onmessage=(msg)=>{
        console.log(msg.data)
    }
    // 监听服务器的关闭
    ws.onclose=()=>{
        console.log('服务器关闭')
    }

    function sendMessage(){
        let msg=document.getElementById("msg").value;
        document.getElementById("msg").value='';
        ws.send(msg)
    }

在前端打印websocket实例

ios建立scoket长连接并发数 socket 长连接_服务器


close方法用于在前端手动断开连接。