web-dev-qa-db-ja.com

TypeError:未定義のプロパティ「emit」を読み取れません

問題は、「this.io.emit」イベントを発生させようとするとTypeErrorが発生することです。このステートメントを「this.io.emit」を「socket.on」ブロック内に書き込んでいる間のみ、それ以外の場合はエラーが発生しません。

これは、他のライブラリを呼び出すメインのserver.jsファイルです。

const express = require('express'),
http = require('http'),
socketio = require('socket.io');

class App{

constructor()
{
    this.port =  process.env.PORT || 81;
    this.Host = `localhost`;        
    this.app = express();
    this.http = http.Server(this.app);
    this.socket = socketio(this.http);
}
appConfig(){
    new config(this.app);
}
appRoutes(){
    new routes(this.app,this.socket).routesDefault();
}
appDefault(){
    this.appConfig();
    this.appRoutes();
    this.http.listen(this.port,this.Host,()=> {
        console.log(`Listening`);
    });
}}

私のサーバー側コードは:

'use strict';
class Routes {

constructor(app,socket) {
    this.app = app;
    this.io = socket;
    this.users=[];
}

routesTemplate()
{
    this.app.get('/',function(req,res){
        res.render('index');
    });
}

socketEvents()
{
    this.io.on('connection',(socket) => {
        socket.on('send message',function(data)
        {
            this.io.emit('new message',data);//here the error lies.
        });
    }); 
}
routesDefault()
{
    this.routesTemplate();
    this.socketEvents();
}}  
module.exports = Routes;

また、socket.on内の「this.users.The length」にアクセスしようとすると、同じTypeErrorが生成され、プロパティの長さを読み取れません。それがなぜ起こっているのか私にはわかりません。この問題の解決を手伝ってください。

クライアント側:

        <script>
        $(function($){
            var socket = io.connect();
            var $messageForm = $('#send-message');
            var $messageBox = $('#message');
            var $chat = $('#chat');

            $messageForm.submit(function(e){
                e.preventDefault();
                socket.emit('send message',$messageBox.val());
                $messageBox.val("");
            });
            socket.on('new message',function(data){
                $chat.append(data+ "<br/>");
            });
        });
    </script>
7
sagar

thisのコンテキストは、コードの問題です。現在のコンテキストを渡すには、bindまたはArrow関数を使用します。 JavaScriptでは、thisの値は関数の呼び出し方法によって定義されます。この場合、socketです。オブジェクト。

socketEvents()
{
    this.io.on('connection',(socket) => {
        socket.on('send message',function(data)
        {
            this.io.emit('new message',data);//here the error lies.
        }bind(this));
    }); 
}

PS:編集済み、このコードは正常に動作します。それについて以下に説明する投稿を提案したいと思います。

ES6の矢印関数とFunction.prototype.bindでバインドされた関数の違い(ある場合)は何ですか?

7
Abhinav Galodha

socket.broadcast.emit()の代わりにio.emit()を使用します

io.on('connection', function(socket){
  socket.broadcast.emit('request', /* */); 
  io.emit('broadcast', /* */); 
  socket.on('reply', function(){ /* */ }); 
});
0
KARTHIKEYAN.A

これは、内部の関数ではこれのコンテキストが異なるためです。

試してください:

socketEvents()
{
    this.io.on('connection',(socket) => {
        socket.on('send message',function(data)
        {
            socket.emit('new message',data);//here the error lies.
        });
    }); 
}
0
Mithilesh Gupta