https://www.workerman.net/plugin/2
根据文档做了浏览器的没啥问题 然后使用了 uniapp打包的在微信里面也可以运行
微信原生的那个要改一下js 也是可以用
这个是微信小程序原生版本的
function Push(options) {
this.doNotConnect = 0;
options = options || {};
options.heartbeat = options.heartbeat || 25000;
options.pingTimeout = options.pingTimeout || 10000;
this.config = options;
this.uid = 0;
this.channels = {};
this.connection = null;
this.pingTimeoutTimer = 0;
Push.instances.push(this);
this.createConnection();
}
Push.prototype.checkoutPing = function () {
var _this = this;
setTimeout(function () {
if (_this.connection.state === 'connected') {
_this.connection.send('{"event":"pusher:ping","data":{}}');
if (_this.pingTimeoutTimer) {
clearTimeout(_this.pingTimeoutTimer);
_this.pingTimeoutTimer = 0;
}
_this.pingTimeoutTimer = setTimeout(function () {
_this.connection.closeAndClean();
if (!_this.connection.doNotConnect) {
_this.connection.waitReconnect();
}
}, _this.config.pingTimeout);
}
}, this.config.heartbeat);
};
Push.prototype.channel = function (name) {
return this.channels[name];
};
Push.prototype.allChannels = function () {
return Object.values(this.channels);
};
Push.prototype.createConnection = function () {
if (this.connection) {
throw Error('Connection already exists');
}
var _this = this;
var url = this.config.url;
this.connection = new Connection({
url: url,
app_key: this.config.app_key,
onOpen: function () {
_this.connection.state = 'connecting';
_this.checkoutPing();
},
onMessage: function (res) {
var params = JSON.parse(res.data);
var event = params.event;
var channel_name = params.channel;
if (_this.pingTimeoutTimer) {
clearTimeout(_this.pingTimeoutTimer);
_this.pingTimeoutTimer = 0;
}
if (event === 'pusher:pong') {
_this.checkoutPing();
return;
}
console.log(event,params)
if (event === 'pusher:error') {
throw Error(params.data.message);
}
if (event === 'pusher_internal:subscription_succeeded') {
var channel = _this.channels[channel_name];
channel.subscribed = true;
channel.processQueue();
channel.emit('pusher:subscription_succeeded');
return;
}
if (event === 'pusher:connection_established') {
_this.connection.socket_id = params.data.socket_id;
_this.connection.state = 'connected';
_this.subscribeAll();
}
var channel = _this.channels[channel_name];
if (channel) {
channel.emit(event, params.data);
}
},
onClose: function () {
_this.connection.state = 'disconnected';
for (var channel_name in _this.channels) {
_this.channels[channel_name].subscribed = false;
}
},
onError: function (err) {
console.error('WebSocket error:', err);
}
});
};
Push.prototype.disconnect = function () {
this.connection.doNotConnect = 1;
this.connection.close();
};
Push.prototype.subscribeAll = function () {
if (this.connection.state !== 'connected') {
return;
}
for (var channel_name in this.channels) {
this.channels[channel_name].processSubscribe();
}
};
Push.prototype.unsubscribe = function (channel_name) {
if (this.channels[channel_name]) {
delete this.channels[channel_name];
if (this.connection.state === 'connected') {
this.connection.send(JSON.stringify({ event: "pusher:unsubscribe", data: { channel: channel_name } }));
}
}
};
Push.prototype.unsubscribeAll = function () {
var channels = Object.keys(this.channels);
if (channels.length) {
if (this.connection.state === 'connected') {
for (var channel_name in this.channels) {
this.unsubscribe(channel_name);
}
}
}
this.channels = {};
};
Push.prototype.subscribe = function (channel_name) {
if (this.channels[channel_name]) {
return this.channels[channel_name];
}
if (channel_name.indexOf('private-') === 0) {
return createPrivateChannel(channel_name, this);
}
if (channel_name.indexOf('presence-') === 0) {
return createPresenceChannel(channel_name, this);
}
return createChannel(channel_name, this);
};
Push.instances = [];
function createChannel(channel_name, push) {
var channel = new Channel(push.connection, channel_name);
push.channels[channel_name] = channel;
channel.subscribeCb = function () {
push.connection.send(JSON.stringify({ event: "pusher:subscribe", data: { channel: channel_name } }));
};
return channel;
}
function createPrivateChannel(channel_name, push) {
var channel = new Channel(push.connection, channel_name);
push.channels[channel_name] = channel;
channel.subscribeCb = function () {
wx.request({
url: push.config.auth,
method: 'POST',
data: { channel_name: channel_name, socket_id: push.connection.socket_id },
success: function (res) {
console.log('Auth response:', res.data); // 打印响应数据,检查格式
var data = res.data;
data.channel = channel_name;
var v = JSON.stringify({ event: "pusher:subscribe", data: data });
console.log(push.config.auth,v)
push.connection.send(v);
},
fail: function (err) {
console.error('Authentication error:', err);
}
});
};
channel.processSubscribe();
return channel;
}
function createPresenceChannel(channel_name, push) {
return createPrivateChannel(channel_name, push);
}
function Connection(options) {
this.options = options;
this.state = 'initialized';
this.doNotConnect = 0;
this.reconnectInterval = 1;
this.socket_id = null;
this.dispatcher = new Dispatcher();
this.on = this.dispatcher.on.bind(this.dispatcher);
this.off = this.dispatcher.off.bind(this.dispatcher);
this.emit = this.dispatcher.emit.bind(this.dispatcher);
this.connect();
}
Connection.prototype.updateNetworkState = function (state) {
if (this.state !== state) {
this.state = state;
this.emit('state_change', { previous: this.state, current: state });
}
};
Connection.prototype.connect = function () {
if (this.state === 'connected' || this.state === 'connecting') {
console.log('Already connecting or connected');
return;
}
if (this.reconnectTimer) {
clearTimeout(this.reconnectTimer);
this.reconnectTimer = 0;
}
this.closeAndClean();
var _this = this;
this.updateNetworkState('connecting');
wx.connectSocket({
url: this.options.url + '/app/' + this.options.app_key,
success: function () {
console.log('Socket connection established');
},
fail: function (err) {
console.error('Socket connection failed:', err);
_this.updateNetworkState('disconnected');
_this.waitReconnect();
}
});
wx.onSocketOpen(function (res) {
_this.reconnectInterval = 1;
if (_this.doNotConnect) {
_this.updateNetworkState('disconnected');
wx.closeSocket();
return;
}
_this.updateNetworkState('connected');
if (_this.options.onOpen) {
_this.options.onOpen(res);
}
});
wx.onSocketMessage(function (res) {
if (_this.options.onMessage) {
_this.options.onMessage(res);
}
});
wx.onSocketClose(function (res) {
_this.updateNetworkState('disconnected');
if (!_this.doNotConnect) {
_this.waitReconnect();
}
if (_this.options.onClose) {
_this.options.onClose(res);
}
});
wx.onSocketError(function (err) {
console.error('Socket error:', err);
_this.close();
if (!_this.doNotConnect) {
_this.waitReconnect();
}
if (_this.options.onError) {
_this.options.onError(err);
}
});
};
Connection.prototype.closeAndClean = function () {
if (this.state === 'connected') {
wx.closeSocket();
}
this.updateNetworkState('disconnected');
};
Connection.prototype.waitReconnect = function () {
if (this.state === 'connected' || this.state === 'connecting') {
return;
}
if (!this.doNotConnect) {
this.updateNetworkState('connecting');
var _this = this;
if (this.reconnectTimer) {
clearTimeout(this.reconnectTimer);
}
this.reconnectTimer = setTimeout(function () {
_this.connect();
}, this.reconnectInterval);
if (this.reconnectInterval < 1000) {
this.reconnectInterval = 1000;
} else {
this.reconnectInterval *= 2;
}
if (this.reconnectInterval > 2000) {
this.reconnectInterval = 2000;
}
}
};
Connection.prototype.send = function (data) {
if (this.state !== 'connected') {
console.error('Cannot send data, not connected');
return;
}
wx.sendSocketMessage({
data: data
});
};
Connection.prototype.close = function () {
this.updateNetworkState('disconnected');
wx.closeSocket();
};
function Channel(connection, channel_name) {
this.subscribed = false;
this.dispatcher = new Dispatcher();
this.connection = connection;
this.channelName = channel_name;
this.subscribeCb = null;
this.queue = [];
__extends(this, this.dispatcher);
var properties = ['on', 'off', 'emit'];
for (var i = 0; i < properties.length; i++) {
this[properties[i]] = this.dispatcher[properties[i]];
}
}
Channel.prototype.processSubscribe = function () {
if (this.connection.state !== 'connected') {
return;
}
this.subscribeCb();
};
Channel.prototype.processQueue = function () {
if (this.connection.state !== 'connected' || !this.subscribed) {
return;
}
for (var i = 0; i < this.queue.length; i++) {
this.queue[i]();
}
this.queue = [];
};
Channel.prototype.trigger = function (event, data) {
if (event.indexOf('client-') !== 0) {
throw new Error("Event '" + event + "' should start with 'client-'");
}
var _this = this;
this.queue.push(function () {
_this.connection.send(JSON.stringify({ event: event, data: data, channel: _this.channelName }));
});
this.processQueue();
};
function Dispatcher(failThrough) {
this.callbacks = {};
this.global_callbacks = [];
this.failThrough = failThrough || function () {};
}
Dispatcher.prototype.on = function (eventName, callback, context) {
if (!this.callbacks[eventName]) {
this.callbacks[eventName] = [];
}
this.callbacks[eventName].push({ fn: callback, context: context });
return this;
};
Dispatcher.prototype.on_global = function (callback) {
this.global_callbacks.push(callback);
return this;
};
Dispatcher.prototype.off = function (eventName, callback, context) {
if (!eventName && !callback && !context) {
this.callbacks = {};
this.global_callbacks = [];
return;
}
if (eventName) {
if (callback || context) {
this.removeCallback(eventName, callback, context);
} else {
delete this.callbacks[eventName];
}
}
};
Dispatcher.prototype.removeCallback = function (eventName, callback, context) {
if (!this.callbacks[eventName]) return;
this.callbacks[eventName] = this.callbacks[eventName].filter(function (cb) {
return (callback && callback !== cb.fn) || (context && context !== cb.context);
});
};
Dispatcher.prototype.emit = function (eventName, data) {
if (this.global_callbacks.length) {
this.global_callbacks.forEach(function (cb) {
cb(eventName, data);
});
}
if (this.callbacks[eventName] && this.callbacks[eventName].length) {
this.callbacks[eventName].forEach(function (cb) {
cb.fn.call(cb.context, data);
});
} else if (this.failThrough) {
this.failThrough(eventName, data);
}
};
function __extends(d, b) {
for (var p in b) {
if (b.hasOwnProperty(p)) {
d[p] = b[p];
}
}
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
export default Push;
都可以聊天
但是 他只能发消息 不能记录历史 想用这个改一下 加个聊天记录 发现这个不好弄呀
想要做一个能记录 聊天记录的 1V1的那种
是不是要用这个
https://www.workerman.net/web-sender
还有个问题 如果是自己改 记录聊天记录 是先发出去再记录数据库 还是 先记录数据库 再发出去
聊天内容转发到消费队列写入数据库就好了,插件只做数据推送就好了
好了解决了 还是用官方的push插件 只要 修改他的配置文件就行
然后再用自己的server 继承 Webman\Push\Server 然后改他的就行了 他的方法都是public
然后去修改 onMessage 就可以记录 聊天记录啦
controller里操作数据库消息,push只做推送,这样既简单,也解耦,性能也好,也不用改造push,方便升级维护。改push操作数据库把以上好处全部抹平了,真没看出有啥意义。
那个84行要改下 这样这个push 就支持微信小程序 网页 uniapp 全都支持啦
let data = JSON.parse(params.data)
_this.connection.socket_id = data.socket_id;