http://www.wtbis.cn/plugin/2
根據(jù)文檔做了瀏覽器的沒啥問題 然后使用了 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); // 打印響應(yīng)數(shù)據(jù),檢查格式
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;
都可以聊天
但是 他只能發(fā)消息 不能記錄歷史 想用這個改一下 加個聊天記錄 發(fā)現(xiàn)這個不好弄呀
想要做一個能記錄 聊天記錄的 1V1的那種
是不是要用這個
http://www.wtbis.cn/web-sender
還有個問題 如果是自己改 記錄聊天記錄 是先發(fā)出去再記錄數(shù)據(jù)庫 還是 先記錄數(shù)據(jù)庫 再發(fā)出去
好了解決了 還是用官方的push插件 只要 修改他的配置文件就行
然后再用自己的server 繼承 Webman\Push\Server 然后改他的就行了 他的方法都是public
controller里操作數(shù)據(jù)庫消息,push只做推送,這樣既簡單,也解耦,性能也好,也不用改造push,方便升級維護。改push操作數(shù)據(jù)庫把以上好處全部抹平了,真沒看出有啥意義。
@damao 你的意思是push只通知A客戶端有沒有接收到新消息,如果接收新的消息就通過ajax訪問controller來獲取消息內(nèi)容然后再作展示之類。當(dāng)A自己發(fā)送消息的時候是直接通過ajax發(fā)送到controller對內(nèi)容進行保存等等,然后再通知B。
假設(shè)A給B發(fā)消息,A ajax調(diào)用controller入庫,然后controller里調(diào)用push接口推送給B,B直接展示消息(無需再獲取消息內(nèi)容,因為推送來的數(shù)據(jù)包含內(nèi)容)。
那個84行要改下 這樣這個push 就支持微信小程序 網(wǎng)頁 uniapp 全都支持啦
let data = JSON.parse(params.data)
_this.connection.socket_id = data.socket_id;