刚学习了一下 推送的那个插件

这个插件 可以推送

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

还有个问题 如果是自己改 记录聊天记录 是先发出去再记录数据库 还是 先记录数据库 再发出去

214 3 1
3个回答

TM

聊天内容转发到消费队列写入数据库就好了,插件只做数据推送就好了

  • 暂无评论

好了解决了 还是用官方的push插件 只要 修改他的配置文件就行
截图
然后再用自己的server 继承 Webman\Push\Server 然后改他的就行了 他的方法都是public

  • 7天前

    然后去修改 onMessage 就可以记录 聊天记录啦

  • damao 7天前

    controller里操作数据库消息,push只做推送,这样既简单,也解耦,性能也好,也不用改造push,方便升级维护。改push操作数据库把以上好处全部抹平了,真没看出有啥意义。

那个84行要改下 这样这个push 就支持微信小程序 网页 uniapp 全都支持啦
let data = JSON.parse(params.data)
_this.connection.socket_id = data.socket_id;

  • 暂无评论
×
🔝