`Openfire` 是一个非常流行的开源 **实时通信(IM)服务器**,它基于 **XMPP 协议**(原名 Jabber),非常适合用于构建企业级即时通讯系统、在线客服、群聊、单聊等应用。
你提到的这个“在线客服”页面正是使用了 XMPP 协议(通过 `strophe.js` 连接 BOSH 接口),而 **Openfire 完全支持这种接入方式**。下面我们详细分析如何用 Openfire 作为后端来运行和接入你的这套客服系统。
---
## ✅ 一、Openfire 简介
| 特性 | 说明 |
|------|------|
| 协议支持 | 原生支持 XMPP 协议 |
| 管理界面 | 提供 Web 管理后台(默认端口 `9090`) |
| 数据库 | 支持嵌入式数据库(HSQLDB)、MySQL、PostgreSQL |
| 扩展性 | 插件丰富(如:消息归档、REST API、文件传输等) |
| 部署 | Java 编写,跨平台,支持 Windows/Linux/macOS |
| 安全 | 支持 TLS 加密、SASL 认证、用户权限管理 |
> ⚙️ 官网地址:[https://www.igniterealtime.org/projects/openfire/](https://www.igniterealtime.org/projects/openfire/)
---
## 🛠️ 二、部署 Openfire 服务(以 Linux 为例)
### 步骤 1:安装 Java 环境
```bash
sudo apt update
sudo apt install openjdk-8-jre -y
```
### 步骤 2:下载并解压 Openfire
```bash
wget https://www.igniterealtime.org/downloadServlet?filename=openfire/openfire_4_7_0.tar.gz -O openfire.tar.gz
tar -xzf openfire.tar.gz -C /opt/
```
### 步骤 3:启动服务
```bash
/opt/openfire/bin/openfire start
```
访问管理后台:
👉 http://your-server-ip:9090
按照向导完成设置(数据库、管理员账号等)
---
## 🔧 三、配置 Openfire 支持 Web 客户端连接(BOSH/WebSocket)
你的前端使用的是 `strophe.js`,它是通过 **BOSH** 或 **WebSocket** 与 XMPP 服务器通信的。
### ✅ 开启 BOSH(默认已开启)
路径:Openfire 后台 → Server → Server Settings → HTTP Binding
确保启用:
- [x] Enable HTTP Binding (BOSH)
- 默认接口:`http://your-domain.com:7070/http-bind`
> 你的 JS 中应设置:
```js
var BOSH_SERVICE = 'http://your-domain.com:7070/http-bind';
```
### ✅ (可选)开启 WebSocket(推荐用于现代浏览器)
路径:Openfire 后台 → Server → Server Settings → HTTP Binding → WebSocket
启用:
- [x] Enable WebSocket
URL 示例:`ws://your-domain.com:7070/ws`
> 注意:生产环境建议配合 Nginx + HTTPS/WSS 使用。
---
## 👤 四、创建用户:客服 & 用户账号
### 1. 创建客服账号(在 Openfire 后台)
登录 Openfire 管理后台 → Users/Groups → Create New User
例如:
- Username: `kefu1`
- Password: `123456`
- Full Name: `客服小张`
- Domain: `yourdomain.com`(即 JID 为 `kefu1@yourdomain.com`)
### 2. 用户账号动态生成(由 PHP 页面传入)
当访客点击“联系客服”时,PHP 应为其创建临时用户名或绑定当前用户 ID。
示例:
```php
$from = "user_" . session_id() . "@yourdomain.com";
$password = generate_token(); // 后端验证后允许登录
```
> 💡 建议使用 Openfire 的 **External Component** 或 **REST API 插件** 动态注册/认证用户。
---
## 🔐 五、安全加固建议
### 方案 1:使用 REST API 插件进行用户认证控制
安装插件:**[Rest API Plugin](https://github.com/igniterealtime/openfire-restAPI)**
功能:
- 动态创建用户
- 修改密码
- 查询状态
- Token 化认证(避免前端暴露真实密码)
#### 示例:通过 API 创建临时用户
```bash
curl -X POST "http://localhost:9090/plugins/restapi/v1/users" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-u admin:admin_password \
-d '{
"username": "user_123",
"password": "temp_pass_123",
"name": "Guest User",
"email": "guest@example.com"
}'
```
然后将 `user_123@yourdomain.com` 和 `temp_pass_123` 返回给前端用于登录。
---
### 方案 2:自定义身份验证模块(高级)
可以开发 Openfire 的 Authentication Provider,对接你的主站数据库,实现免密登录或 token 登录。
---
## 📡 六、前端连接 Openfire(Strophe.js 示例)
```html
<script src="js/jquery-1.6.2.min.js"></script>
<script src="js/strophe.js"></script>
<script>
var BOSH_SERVICE = 'http://your-domain.com:7070/http-bind';
var connection = null;
function log(msg) {
$('#log').append('<p>' + msg + '</p>');
}
function onConnect(status) {
if (status === Strophe.Status.CONNECTING) {
log('正在连接...');
} else if (status === Strophe.Status.CONNFAIL) {
log('连接失败');
} else if (status === Strophe.Status.DISCONNECTED) {
log('已断开');
} else if (status === Strophe.Status.CONNECTED) {
log('连接成功!开始接收消息...');
// 注册消息处理器
connection.addHandler(onMessage, null, 'message', 'chat');
}
}
function onMessage(msg) {
var from = msg.getAttribute('from');
var to = msg.getAttribute('to');
var elems = msg.getElementsByTagName('body');
if (elems.length > 0) {
var body = elems[0];
var text = Strophe.getText(body);
insertOtherMessage(text, from);
$("#scroll_div").scrollTop($(".scroll_inner").height());
}
return true;
}
function sendMessage(toJid, message) {
var msg = $msg({
to: toJid,
type: 'chat',
from: $('#from').val()
}).c('body').t(message).up()
.c('active', {xmlns: 'http://jabber.org/protocol/chatstates'});
connection.send(msg.tree());
}
$(document).ready(function () {
var fromJid = $('#from').val();
var password = $('#password').val();
connection = new Strophe.Connection(BOSH_SERVICE);
connection.connect(fromJid, password, onConnect);
// 发送按钮事件
$('#btn_send').click(function () {
var msg = $('#editor').val().trim();
if (!msg) return;
sendMessage($('#to').val(), msg);
insertUserMessage(msg);
$('#editor').val('');
});
// 回车发送
$('#editor').keypress(function (e) {
if (e.which === 13 && !e.shiftKey) {
e.preventDefault();
$('#btn_send').click();
}
});
});
</script>
```
---
## 🔄 七、消息模板插入函数补充
```javascript
function insertUserMessage(content) {
var template = $('#from_html').html();
var timeStr = new Date().toLocaleTimeString([], {hour:'2-digit', minute:'2-digit'});
var html = template
.replace(/from_name/g, $('#username').val())
.replace(/send_time/, timeStr)
.replace(/msg_content/, $('<div>').text(content).html()) // 转义 XSS
.replace(/script_from_id/, 'msg_' + Date.now());
$(html).appendTo('.scroll_inner');
}
function insertOtherMessage(content, fromJid) {
var template = $('#to_html').html();
var name = fromJid.split('@')[0].replace('kefu', '客服');
var timeStr = new Date().toLocaleTimeString([], {hour:'2-digit', minute:'2-digit'});
var html = template
.replace(/to_name/g, name)
.replace(/send_time/, timeStr)
.replace(/msg_content/, $('<div>').text(content).html())
.replace(/script_to_id/, 'msg_' + Date.now());
$(html).appendTo('.scroll_inner');
}
```
---
## ✅ 八、生产环境优化建议
| 项目 | 建议 |
|------|------|
| 域名 | 绑定正式域名,如 `im.yourshop.com` |
| HTTPS | 使用 Let's Encrypt 证书,Nginx 反向代理 |
| WebSocket | 替代 BOSH,降低延迟 |
| 消息存档 | 安装 `monitoring` 插件记录聊天历史 |
| 高可用 | 集群部署多个 Openfire 实例 + ZooKeeper |
| 监控 | 集成 Prometheus + Grafana 监控连接数 |
---
## 📦 九、常用插件推荐
| 插件 | 功能 |
|------|------|
| **REST API** | 外部系统调用用户管理 |
| **Monitoring** | 存储消息历史、离线消息 |
| **Fastpath** | 完整的 Web 客服系统(排队、转接、评价) |
| **SIP Phone** | 视频语音通话 |
| **Clustering** | 支持多节点集群 |
> 插件下载地址:[https://www.igniterealtime.org/projects/openfire/plugins.jsp](https://www.igniterealtime.org/projects/openfire/plugins.jsp)
---
## ✅ 总结:Openfire 是否适合你的客服系统?
✅ **非常适合!**
| 优势 | 说明 |
|------|------|
| 即开即用 | 不需要自己实现 XMPP 协议 |
| 支持 Web 接入 | 完美兼容 strophe.js |
| 易于管理 | 图形化后台,无需命令行 |
| 社区活跃 | 文档齐全,问题容易解决 |
| 可扩展性强 | 插件机制完善 |
---
###