0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

メモ: Socket.IO の set と get メソッドは廃止されている

Last updated at Posted at 2020-05-10

前置き

Illustrator絵を描いたので、それらを使ってゲームを作ってみました。
以前はJavaScriptで絵をただランダムに表示させるだけだったのですが、Nuxt.jsを使ってゲームに作り変え、遊び方説明ページを加えたり結果を表示させるようにしたり、英語対応やダークモードも実装したりしました。

 
 
 

しかし、

何かモヤモヤとしたものが残っています。

そして、

そのモヤモヤは日々募るばかりです。

なぜか?

 
 
 
 
 
 

そうです。

一人でしか遊べないからです。
誰かと対戦できるようにしたいのです。

調べると、

Socket.IO enables real-time, bidirectional and event-based communication.
It works on every platform, browser or device, focusing equally on reliability and speed.

Node.js用の双方向通信サポートライブラリであるSocket.IOを使うと対戦ゲームに作り変えられるような予感がします。

そこで、Socket.IOを試しに一度使ってみようと思い、『はじめてのNode.jsプログラミング Kindle版』(松尾 勇也 著) の通りにチャットを作ってみました。

本題

前置きが長くなりましたが、ここからが本題のメモ書きです。

以下はserver.jsのこの部分の抜粋です。

server.js
// socket.ioの設定
io.sockets.on('connection', function(socket) {
	socket.on('login', function(name) {
		// 接続しているユーザー全員にloginを送信
		var time = new Date().toJSON();
		io.sockets.emit('login', time, name);
		// name を記憶
		socket.set('name', name);
	});
	socket.on('post', function(name, text) {
		// 接続しているユーザー全員にpostを送信
		var time = new Date().toJSON();
		io.sockets.emit('post', time, name, text);
	});
	socket.on('disconnect', function() {
		// 接続しているユーザー全員にlogoutを送信
		socket.get('name', function(err, name) {
			var time = new Date().toJSON();
			io.sockets.emit('logout', time, name);
		});
	});
});

Matsuo Yuya. Hajimete no Nodejs Programming (Japanese Edition) (Kindle の位置No.741-750). Kindle 版. より抜粋)

node server.jsとしたところ、以下のエラーが発生しました。

root@7f37fa299545:/app# node server.js 
/app/server.js:18
        socket.set('name', name);
               ^

TypeError: socket.set is not a function
    at Socket.<anonymous> (/app/server.js:18:16)
    at Socket.emit (events.js:310:20)
    at /app/node_modules/socket.io/lib/socket.js:528:12
    at processTicksAndRejections (internal/process/task_queues.js:79:11)

サーバーに接続すると login イベントがクライアントに向けて発信されます。その中でユーザーの入力した名前を記憶させるための記述の中で set を用いています

調べてみたところ、

node.js - socket.io socket.set and socket.get - what is the callback argument for? - Stack Overflow』の回答によると

The get and set functions on the socket object were removed in version 1.x.

getset は廃止になっているようです。

ドットインストールにも載ってました。

Socket.IO の 1.0 から socket.set と socket.get メソッドが廃止されたため、そのまま動作させるとエラーが発生してしまいます。

そこで、以下のように修正したところうまくいきました。
(いくつか修正していますが、「修正」と書いたところの修正のみがエラーに関連している部分です。)

server.js
//socket.ioの設定
io.sockets.on('connection', socket => {
    socket.on('login', name => {
        //接続しているユーザー全員にloginを送信
        const time = new Date().toJSON()
        io.sockets.emit('login', time, name)
        //nameを記憶
        socket.client_name = name
    })
    socket.on('post', (name, text) => {
        // 接続しているユーザー全員にpostを送信
        const time = new Date().toJSON()
        io.sockets.emit('post', time, name, text) // 修正
    })
    socket.on('disconnect', () => {
        // 接続しているユーザー全員にlogoutを送信
        const time = new Date().toJSON() // 修正
        io.sockets.emit('logout', time, socket.client_name) // 修正
    })
})

GitHub

脇道

スタイルも修正してみました。
自分が送信したメッセージは画面の右に表示されて、他の人のメッセージは画面の左に投稿されるような見た目にしようと思ったので、以下のことを試しました。

server.js
    socket.on('post', (name, text) => {
        // 接続しているユーザー全員にpostを送信
        const time = new Date().toJSON()
        socket.emit('self-post', time, name, text)
        socket.broadcast.emit('others-post', time, name, text)
    })

[GitHub]
(https://github.com/toshikisugiyama/chat_app_with_nodejs_express_socketio/blob/ca1b09e601725a33a1fed6a2d6dd31fc5a27f329/server.js#L20-L25)

上記のように自分の投稿と他人の投稿をそれぞれ socket.emitsocket.broadcast.emit を使い分けて別のイベントとして発信することで、

index.html
        socket.on('self-post', (time, name, text) => {
            const content = document.createElement('div')
            content.className = 'self'
            createMessageNode(content, text, time, name)
        })
        socket.on('others-post', (time, name, text) => {
            const content = document.createElement('div')
            content.className = 'others'
            createMessageNode(content, text, time, name)
        })

GitHub

自分の投稿にはself、他人の投稿にはothersのようにそれぞれ別のクラスを設定でき、別のスタイルを割り当てることができました。

file.gif

おわりに

次はNuxt.jsで作っているゲームにSocket.IOを組み合わせて対戦できるようにしたいです。

Nuxt.jsでSocket.IOを使うには『Nuxt.js (Vue.js) + Express + Socket.IO でリアルタイムWeb (チャット) を体験する』が参考になるのかなと思っているのですが、やってみないとまだわかりません。

参考

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?