Php laravel广播-客户端多次接收一个响应

Php laravel广播-客户端多次接收一个响应,php,reactjs,laravel,broadcasting,Php,Reactjs,Laravel,Broadcasting,我正在创建一个简单的实时聊天应用程序(laravel,reactjs,pusher) 服务器只需从客户端(ReactJs)获取名称和文本消息,将数据存储在数据库中,然后将新数据传递给我的事件,事件将其传递给客户端 它可以工作,但我的问题是客户端中的侦听器多次接收数据,每次请求后接收数据的次数会增加。 我只想从服务器获取一次数据 我的控制器: class MessageController extends Controller { public function index(Request

我正在创建一个简单的实时聊天应用程序(
laravel,reactjs
pusher

服务器只需从客户端(ReactJs)获取名称和文本消息,将数据存储在数据库中,然后将新数据传递给我的事件,事件将其传递给客户端

它可以工作,但我的问题是客户端中的侦听器多次接收数据,每次请求后接收数据的次数会增加。
我只想从服务器获取一次数据

我的控制器:

class MessageController extends Controller
{
    public function index(Request $request){
       $message = Message::create([
        'name' => $request->name,
        'text' => $request->text
      ])->toArray();

     return event(new MessageEvent($message));
    }
}
class MessageEvent implements ShouldBroadcast
{
  use SerializesModels;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public $data;
    public function __construct($message)
    {
        $this->data = $message;

    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn(){
       return 'messages';
    }

    public function broadcastAs(){
        return 'MessageEvent';
    }

    public function broadcastWith(){
    return  [
        'id' => $this->data['_id'],
        'name' => $this->data['name'],
        'text' => $this->data['text']
      ];
    }
}
export function ChatPage({ dispatch, getMessages, sendMessage, chatPage }) {
  useInjectReducer({ key: 'chatPage', reducer });
  useInjectSaga({ key: 'chatPage', saga });
  const [text, setText] = useState('');

  window.Echo = new Echo({
    broadcaster: 'pusher',
    key: '8171e9879fae800e8fef',
    cluster: 'ap2',
    forceTLS: true,
  });

  const channel = window.Echo.channel('messages');
  channel.listen('.MessageEvent', function(data) {
    console.log(data, 'index');
  });

  return (
    <ChatWrapper>
      <Helmet>
        <title>ChatPage</title>
        <meta name="description" content="Description of ChatPage" />
      </Helmet>
      <div className="container">
        {chatPage.data
          ? chatPage.data.map(item => (
              <div
                className={
                  item.name === localStorage.getItem('chat')
                    ? 'item-rigth'
                    : 'item-left'
                }
                key={item.id}
              >
                <span>
                  {item.name}
                  <hr />
                  {item.text}
                </span>
              </div>
            ))
          : null}
        <div className="form">
          <div>
            <input
              type="text"
              value={text}
              onChange={e => setText(e.target.value)}
              placeholder="Type Something..."
            />
            <img
              src={Send}
              onClick={() => {
                sendMessage(text);
                setText('');
              }}
            />
          </div>
        </div>
      </div>
    </ChatWrapper>
  );
}

ChatPage.propTypes = {
  dispatch: PropTypes.func.isRequired,
};

const mapStateToProps = createStructuredSelector({
  chatPage: makeSelectChatPage(),
});

function mapDispatchToProps(dispatch) {
  return {
    dispatch,
    sendMessage: text => dispatch(messageAction(text)),
    getMessages: data => dispatch(messageSuccessAction(data)),
  };
}

const withConnect = connect(
  mapStateToProps,
  mapDispatchToProps,
);

export default compose(
  withConnect,
  memo,
)(ChatPage);
我的活动:

class MessageController extends Controller
{
    public function index(Request $request){
       $message = Message::create([
        'name' => $request->name,
        'text' => $request->text
      ])->toArray();

     return event(new MessageEvent($message));
    }
}
class MessageEvent implements ShouldBroadcast
{
  use SerializesModels;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public $data;
    public function __construct($message)
    {
        $this->data = $message;

    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn(){
       return 'messages';
    }

    public function broadcastAs(){
        return 'MessageEvent';
    }

    public function broadcastWith(){
    return  [
        'id' => $this->data['_id'],
        'name' => $this->data['name'],
        'text' => $this->data['text']
      ];
    }
}
export function ChatPage({ dispatch, getMessages, sendMessage, chatPage }) {
  useInjectReducer({ key: 'chatPage', reducer });
  useInjectSaga({ key: 'chatPage', saga });
  const [text, setText] = useState('');

  window.Echo = new Echo({
    broadcaster: 'pusher',
    key: '8171e9879fae800e8fef',
    cluster: 'ap2',
    forceTLS: true,
  });

  const channel = window.Echo.channel('messages');
  channel.listen('.MessageEvent', function(data) {
    console.log(data, 'index');
  });

  return (
    <ChatWrapper>
      <Helmet>
        <title>ChatPage</title>
        <meta name="description" content="Description of ChatPage" />
      </Helmet>
      <div className="container">
        {chatPage.data
          ? chatPage.data.map(item => (
              <div
                className={
                  item.name === localStorage.getItem('chat')
                    ? 'item-rigth'
                    : 'item-left'
                }
                key={item.id}
              >
                <span>
                  {item.name}
                  <hr />
                  {item.text}
                </span>
              </div>
            ))
          : null}
        <div className="form">
          <div>
            <input
              type="text"
              value={text}
              onChange={e => setText(e.target.value)}
              placeholder="Type Something..."
            />
            <img
              src={Send}
              onClick={() => {
                sendMessage(text);
                setText('');
              }}
            />
          </div>
        </div>
      </div>
    </ChatWrapper>
  );
}

ChatPage.propTypes = {
  dispatch: PropTypes.func.isRequired,
};

const mapStateToProps = createStructuredSelector({
  chatPage: makeSelectChatPage(),
});

function mapDispatchToProps(dispatch) {
  return {
    dispatch,
    sendMessage: text => dispatch(messageAction(text)),
    getMessages: data => dispatch(messageSuccessAction(data)),
  };
}

const withConnect = connect(
  mapStateToProps,
  mapDispatchToProps,
);

export default compose(
  withConnect,
  memo,
)(ChatPage);
我的客户端聊天室:

class MessageController extends Controller
{
    public function index(Request $request){
       $message = Message::create([
        'name' => $request->name,
        'text' => $request->text
      ])->toArray();

     return event(new MessageEvent($message));
    }
}
class MessageEvent implements ShouldBroadcast
{
  use SerializesModels;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public $data;
    public function __construct($message)
    {
        $this->data = $message;

    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn(){
       return 'messages';
    }

    public function broadcastAs(){
        return 'MessageEvent';
    }

    public function broadcastWith(){
    return  [
        'id' => $this->data['_id'],
        'name' => $this->data['name'],
        'text' => $this->data['text']
      ];
    }
}
export function ChatPage({ dispatch, getMessages, sendMessage, chatPage }) {
  useInjectReducer({ key: 'chatPage', reducer });
  useInjectSaga({ key: 'chatPage', saga });
  const [text, setText] = useState('');

  window.Echo = new Echo({
    broadcaster: 'pusher',
    key: '8171e9879fae800e8fef',
    cluster: 'ap2',
    forceTLS: true,
  });

  const channel = window.Echo.channel('messages');
  channel.listen('.MessageEvent', function(data) {
    console.log(data, 'index');
  });

  return (
    <ChatWrapper>
      <Helmet>
        <title>ChatPage</title>
        <meta name="description" content="Description of ChatPage" />
      </Helmet>
      <div className="container">
        {chatPage.data
          ? chatPage.data.map(item => (
              <div
                className={
                  item.name === localStorage.getItem('chat')
                    ? 'item-rigth'
                    : 'item-left'
                }
                key={item.id}
              >
                <span>
                  {item.name}
                  <hr />
                  {item.text}
                </span>
              </div>
            ))
          : null}
        <div className="form">
          <div>
            <input
              type="text"
              value={text}
              onChange={e => setText(e.target.value)}
              placeholder="Type Something..."
            />
            <img
              src={Send}
              onClick={() => {
                sendMessage(text);
                setText('');
              }}
            />
          </div>
        </div>
      </div>
    </ChatWrapper>
  );
}

ChatPage.propTypes = {
  dispatch: PropTypes.func.isRequired,
};

const mapStateToProps = createStructuredSelector({
  chatPage: makeSelectChatPage(),
});

function mapDispatchToProps(dispatch) {
  return {
    dispatch,
    sendMessage: text => dispatch(messageAction(text)),
    getMessages: data => dispatch(messageSuccessAction(data)),
  };
}

const withConnect = connect(
  mapStateToProps,
  mapDispatchToProps,
);

export default compose(
  withConnect,
  memo,
)(ChatPage);
导出函数ChatPage({dispatch,getMessages,sendMessage,ChatPage}){
useInjectReducer({key:'chatPage',reducer});
useInjectSaga({key:'chatPage',saga});
const[text,setText]=useState(“”);
window.Echo=新的Echo({
广播员:“推手”,
键:“8171e9879fae800e8fef”,
群集:“ap2”,
是的,
});
const channel=window.Echo.channel('messages');
channel.listen('.MessageEvent',函数(数据){
log(数据“索引”);
});
返回(
聊天页
{chatPage.data
?chatPage.data.map(项=>(
{item.name}

{item.text} )) :null} setText(e.target.value)} 占位符=“键入某物…” /> { 发送消息(文本); setText(“”); }} /> ); } ChatPage.propTypes={ 调度:需要PropTypes.func.isRequired, }; const mapStateToProps=createStructuredSelector({ chatPage:makeSelectChatPage(), }); 功能图DispatchToprops(调度){ 返回{ 派遣, sendMessage:text=>dispatch(messageAction(text)), getMessages:data=>dispatch(messageSuccessAction(data)), }; } const withConnect=connect( MapStateTops, mapDispatchToProps, ); 导出默认组合( 通过连接, 备忘录, )(聊天页);
我认为当我从postman调用事件时,它可以正常工作,但当我从客户端向服务器请求时,它会给出多次响应(我认为这是为了重新呈现页面)

我到底该怎么办?

嘿,我解决了这个问题:)

我将我的listener部分放入
useffect

  useEffect(() => {
    window.Echo = new Echo({
      broadcaster: 'pusher',
      key: '8171e9879fae800e8fef',
      cluster: 'ap2',
      forceTLS: true,
    });
    const channel = window.Echo.channel('messages');
    channel.listen('.MessageEvent', function(data) {
      console.log(data, 'data');
    });
  }, []);

您是否尝试监视pusher仪表板?我只是从pusher调试控制台调用事件,它起作用了我的问题在客户端确保pusher不会一次获得单个事件的多个订阅我想是的,我该怎么办