次をコピペすればlocalhost
のport7000
で動くはず。
import io from 'socket.io'
const socket = io(7000)
socket.on('connection', function (socket) {
console.log(`a user connected[id:${socket.id}]`)
//socket.emit()等の処理はここに記述
})
Socket.io(サーバー側)をES6以降のimport文で宣言しようとすると次のエラーに出くわす。
TypeError: socket.on is not a function
これは以前のrequireで宣言していた時の次ようなコード
const PORT = 7000
const io = require('socket.io')(PORT)
これの (PORT) の部分がどういう構文なのか知らずに使っていると
import io from 'socket.io'(PORT) //これはエラー
このような構文は無いので
import io from 'socket.io'
こうしてしまっているからエラーになる。
これは require('socket.io')
が「関数」を返しているという点に注意だ。
つまり 関数(PORT)
の記述と同義であり'socket.io'
から引っ張ってきた関数にPORT
を引数で渡してやった結果(このreturn
)がio
に入っている、ということだ。
私はこの構文の書き方について詳しい説明を見たことがない。
海外のフォーラムでちらっと解説を見かけたことがある程度で恐らく初心者は確実に意味不明だろう。
import io from 'socket.io'
io.on('connection', function (socket) {
...
このコードは冒頭で述べたエラーになる。なぜだろうか?
まず1行目のimportによりio
には関数が入っている。
2行目を見て欲しい。io.on()
でメソッドが呼ばれている。メソッドが呼べるのはオブジェクト(またはクラス)だけだ。
既に冒頭で貼り付けているがもう一度
import io from 'socket.io'
const socket = io(7000)
socket.on('connection', function (socket) {
...
これなら動作する。
これは単純に「ポートを指定したから」という理由ではなく少し内部を理解しておきたい。
先程述べたようにimport
した段階でio
は関数である。
そしてこのio
という関数にポート(の他にオプション等も引数で入れられる)を渡してやって初めてreturn
により使用可能なオブジェクトが帰ってくるという仕組みだ。
これはJavaScriptの構文の勉強でありSocket.ioの動作のクセでもある。
なんとも説明し難い使い方だ。
import IOOOOOOOOOOOOOOO from 'socket.io'
のように適当な名前にしてもOKだ。
以前はOKじゃなかった気がしたが・・・よくわからんがまぁ動いてるからヨシ!だ(Node.js - v13.12.0
)
これでサーバー側は覚えたので、クライアント側もライブラリ名を変えるだけ...と思っているとエラーがでる。
※クライアント用のライブラリは socket.io-client
のため別途インストールが必要。
例えば次のコードはエラーだ。
import io from "socket.io-client"
const socket = io(7000)
socket.on("connect", () => {
...
これはこれまでの説明で見れば動きそうに見えるが動かない。
では、どうするのかと言うとio
の引数を変更する。
const socket = io("localhost:7000")
クライアント側はURLを設定することになるのでここはポートの数字ではなく文字列で渡す必要がある。
2020/06/16: Vue.jsなら最初はとりあえずこうするという例を記載する
import io from "socket.io-client";
export default {
name: "HelloWorld",
data: () => ({
socket: io("localhost:7000")
}),
mounted() { //mountedはアロー関数にしてはいけない
this.socket.on("connect", () => {
console.log("connected");
});
},
methods: {}
};
Socket.ioはNode.jsならフロントエンドとの通信に頻繁に利用する(他にもっといい方法があるかもしれないが)ことになるが適当にコーディングしているといつも「あれ、なんでエラー?」と時間を消費するケースが増えたためこの記事を執筆した。
公式はimport
に対応している記述があるが、もうすこしes6向けのコードが解説されても良いのではないかと思った。
まだNode.jsではes6以降で書くユーザーは少ないかもしれないが恐らくハマっている人も少なくはないのではないだろうか。