【问题标题】:socket.io code organizing and timing ES6socket.io 代码组织和计时 ES6
【发布时间】:2018-06-03 12:05:29
【问题描述】:

我有一个非常简单的实验性应用程序,您单击一个显示按钮,然后使用 socket.io 将图像实时显示给所有客户端。现在它在大多数情况下确实有效。但是我遇到了一个问题(我的原始问题:socket.io emit on connect),当客户端连接时没有发生事件,但我在这个线程的帮助下解决了这个问题:socket.emit on sever side is ignored after connection?

基本上,我的“new-client-append 事件”检索数据(字符串形式的 html),因此当新客户端连接时,它会显示当前客户端看到的相同数据(类似于连接到聊天室并且能够查看所有聊天记录)。我不得不重新组织我的代码,以便我的“新客户端附加”事件发生,如果我手动输入数据,我可以让它工作。我的新问题是现在我不得不重新组织我的代码,我的“new-client-append”事件依赖于我在类中设置的变量,因此它不再可识别。我对 JS 比较陌生,我怎样才能让我的变量被识别,为什么会这样?我曾尝试将事件移动到我的代码的不同位置,但没有成功。它是this.mainContainer 变量。

客户

import $ from 'jquery';
import SaveInput from './SaveInput';
import io from 'socket.io-client';

// make connection
const socket = io.connect('localhost:3000');


**socket.on('new-client-append', (data) => {
  console.log('NEW CLIENT ENTERED');
  console.log('on new-client-clone ' + JSON.stringify(data));

    this.mainContainer.append(data);

});**

socket.on('connect_error', function(){
    console.log('fail');
});


class Display extends SaveInput {

    constructor(){

    this.mainContainer = $('.main-container');
    this.pGrid = $('.pic-grid-container');
    this.display = $('#btn-display');

    this.buttons();
  }

  buttons (){

    // click buttons
    this.display.click(this.displayEls.bind(this));



  //display images 
  displayEls() {

    let img = 'https://secure.gravatar.com/avatar/22f38e0216f57af53a1776fb2a72c436?s=60&d=wavatar&r=g';
    let $picContainer = $('<div class="picture-frame"></div>');
    let  $newImg = $('<img>');

    // clone pic-grid-container
    let htmlClone = this.pGrid.clone();
    let stringClone = htmlClone.html();

    // EMIT

    //send image url
    socket.emit('client-image', {
      image: img
    });

    // send dom clone to server
    socket.emit('new-client-append', {
      clone: stringClone
    });

    // LISTEN

    // append image in real time
    socket.on('client-image', (data) => {

        let foo = data.image.toString();

        $newImg.attr('src', foo);
        // console.log(data);
        // console.log(foo);
        $newImg.appendTo($picContainer);
        this.pGrid.append($picContainer);

        // console.log('html clone ' + JSON.stringify(htmlClone));
        // console.log('string clone ' + stringClone);
    });

}

export default Display;

服务器

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


// app set up
const app = express();
const server = http.Server(app);
// const  = new socket(server);
let port = process.env.PORT || 3000;

// static files
app.use(express.static('app'));

// socket setup & pass SERVER
const io = new socketIO(server);

let jqueryImage;

// on client connect
io.on('connection', (socket) => {

  console.log('client has entered...');

  socket.emit('new-client-append', jqueryImage);


    // events
    socket.on('client-image', function(data){
        console.log('SERVER ' + data.image);
        io.sockets.emit('client-image', data);
    });


    socket.on('new-client-append', function(data){
            jqueryImage = data.clone;
            console.log('jqueryImage ' + JSON.stringify(jqueryImage));
      });



    // errors
    io.on('error', function (err) {
        console.log(err);
    });

    io.on('connect_error', function(){
        console.log('fail');
    });

});


server.listen(port, () => {
    console.log('server running....');
});

更新

添加了建议的代码,从显示对象调用主容器。但它是说它没有定义。

socket.on('new-client-append', (data) => {
  console.log('NEW CLIENT ENTERED');
  console.log('on new-client-clone ' + JSON.stringify(data));

    **display.mainContainer.append(data);**

});

我创建对象的文件

import SaveInput from './modules/SaveInput';
import Display from './modules/Display';


const saveInput = new SaveInput();
const display = new Display ();

【问题讨论】:

    标签: javascript websocket ecmascript-6 socket.io


    【解决方案1】:

    你的 socket.on 函数有

    this.mainContainer.append(data);
    

    这意味着您已将 mainContainer 属性附加到套接字对象。因为您没有这样做,而是在您的 Display(子)类中声明它,所以它附加到您创建的 Display 对象。我似乎找不到它,但是在某个地方,无论哪里需要这个脚本,都有一个

    variable = new Display();
    

    你必须用它的名字来调用这个 mainContainer 对象。找到启动 Display 对象的代码,然后使用

    theVarNameYouFound.mainContainer.append(thatThing);
    

    【讨论】:

    • 这是有道理的。我根据您的建议调整了我的代码(在上面进行了编辑)。现在是说显示对象没有定义。
    • 是的,不幸的是,它不能那样工作。正在导出此类,但未导入主脚本。所以这个js脚本范围内不存在这个变量。
    • 另外,您只是导出和导入 Display 类,因此脚本的其余部分基本上没有用。您的套接字代码应该包含在从该类创建实际对象的脚本中。我可能应该指定。
    猜你喜欢
    • 1970-01-01
    • 2012-07-05
    • 1970-01-01
    • 1970-01-01
    • 2018-10-12
    • 2018-01-08
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多