GolangのWebsocketでクライアントが送信したデータが他のクライアントに反映されない
GolangでWebsocketをつかって写真を共有するWeb Applicationを作っています。
あるクライアントが写真を投稿すると、すぐに、ほかのクライアントに表示されている写真がそれに更新されるようにしたいです。
そのために*websocket.Conn
をws_array
という配列に入れ、データをSendするときはforで配列から取り出してデータを送信しています。
ある写真が投稿されたら、ほかのクライアントに表示されている写真も投稿と同時に更新されるようにしたいのですが、写真が投稿されてもほかのクライアントの写真が更新されません。
なぜなのでしょうか?
Serverのコード
package main
import (
"database/sql"
"fmt"
"github.com/go-gorp/gorp"
_ "github.com/mattn/go-sqlite3"
"golang.org/x/net/websocket"
"log"
"net/http"
)
type Picture struct {
Id int64
Data []byte
Name string
Type string
}
var debug = false
var photodb = "./db/photo.sqlite3"
func main() {
http.Handle("/layouts/css/", http.StripPrefix("/layouts/css/", http.FileServer(http.Dir("layouts/css"))))
http.Handle("/", http.FileServer(http.Dir(".")))
http.Handle("/chat", websocket.Handler(data_handle))
fmt.Println(":8249")
err := http.ListenAndServe(":8249", nil)
if err != nil {
panic("ListenAndServe: " + err.Error())
}
}
func InitDb() (*gorp.DbMap, error) {
db, err := sql.Open("sqlite3", photodb)
if err != nil {
fmt.Println(err)
return nil, err
}
dbmap := &gorp.DbMap{Db: db, Dialect: gorp.SqliteDialect{}}
dbmap.AddTableWithName(Picture{}, "picture").SetKeys(true, "Id")
err = dbmap.CreateTablesIfNotExists()
if err != nil {
return nil, err
}
return dbmap, nil
}
func insertPic(pic *Picture) {
dbmap, err := InitDb()
if err != nil {
log.Fatalln("InitDb error:", err)
}
err = dbmap.Insert(pic)
if err != nil {
log.Fatalln("Insert error:", err)
}
}
func data_receive(ws *websocket.Conn) {
for {
var b Picture
if err := websocket.JSON.Receive(ws, &b); err != nil {
if debug {
fmt.Println(b)
}
fmt.Println("Receive error:", err)
} else {
insertPic(&b)
for _, con := range ws_array {
go func() {
err = websocket.JSON.Send(con, b)
fmt.Println("con:", con)
if err != nil {
fmt.Println("Send error:", err)
}
}()
}
}
}
}
var ws_array []*websocket.Conn // *websocket.Connを入れる配列
func data_handle(ws *websocket.Conn) {
ws_array = append(ws_array, ws)
data_receive(ws)
}
ClientのJavaScript
var ws = new WebSocket("ws://localhost:8249/chat")
ws.onerror = function (err) {
console.error("Error: " + err);
}
var img = document.getElementById("hello");
var f = document.getElementById("file");
var file_reader = new FileReader();
f.onchange = function () {
var filelist = this.files;
var file = filelist[0];
file_reader.onload = function (e) {
var data = e.target.result;
var b64 = data.slice(data.indexOf(",") + 1);
var s = {"Name": file.name, "Data": b64, "Type": file.type};
console.log(JSON.stringify(s));
ws.send(JSON.stringify(s));
}
file_reader.readAsDataURL(file);
}
ws.onmessage = function (e) {
console.log("Received");
var obj = JSON.parse(e.data);
var bytes = atob(obj.Data.replace(/^.*,/, ''));
var b = new Uint8Array(obj.Data.length);
for (var i = 0; i < obj.Data.length; i++) {
b[i] = bytes.charCodeAt(i);
}
var blob = new Blob([b.buffer], {type: obj.Type});
var url = URL.createObjectURL(blob);
img.src = url;
}
HTML
<!DOCTYPE html>
<html lang="ja">
<head>
<title>Websocket json</title>
<meta charset="utf-8">
<link rel="stylesheet" href="websocket.css">
</head>
<body>
<input type="file" id="file" accept="image/*">
<img id="hello">
<script src="websocket_json.js"></script>
</body>
</html>
<!DOCTYPE html>
<html lang="ja">
<head>
<title>Websocket json</title>
<meta charset="utf-8">
<link rel="stylesheet" href="websocket.css">
</head>
<body>
<input type="file" id="file" accept="image/*">
<img id="hello">
<script src="websocket_json.js"></script>
</body>
</html>