144 lines
2.7 KiB
Go
144 lines
2.7 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
rice "github.com/GeertJohan/go.rice"
|
|
"github.com/gorilla/websocket"
|
|
"github.com/ipfs/go-car"
|
|
"github.com/ipfs/go-datastore"
|
|
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
|
"github.com/libp2p/go-libp2p"
|
|
"github.com/libp2p/go-libp2p-core/peer"
|
|
pnet "github.com/libp2p/go-libp2p-pnet"
|
|
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
|
|
|
"github.com/filecoin-project/lotus/build"
|
|
"github.com/filecoin-project/lotus/node/modules/lp2p"
|
|
)
|
|
|
|
var topic = "/fil/headnotifs/"
|
|
|
|
func init() {
|
|
genBytes := build.MaybeGenesis()
|
|
if len(genBytes) == 0 {
|
|
topic = ""
|
|
return
|
|
}
|
|
|
|
bs := blockstore.NewBlockstore(datastore.NewMapDatastore())
|
|
|
|
c, err := car.LoadCar(bs, bytes.NewReader(genBytes))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
if len(c.Roots) != 1 {
|
|
panic("expected genesis file to have one root")
|
|
}
|
|
|
|
fmt.Printf("Genesis CID: %s\n", c.Roots[0])
|
|
topic = topic + c.Roots[0].String()
|
|
}
|
|
|
|
var upgrader = websocket.Upgrader{
|
|
WriteBufferSize: 1024,
|
|
CheckOrigin: func(r *http.Request) bool {
|
|
return true
|
|
},
|
|
}
|
|
|
|
func main() {
|
|
if topic == "" {
|
|
fmt.Println("FATAL: No genesis found")
|
|
return
|
|
}
|
|
|
|
ctx := context.Background()
|
|
|
|
protec, err := pnet.NewProtector(strings.NewReader(lp2p.LotusKey))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
host, err := libp2p.New(
|
|
ctx,
|
|
libp2p.Defaults,
|
|
libp2p.PrivateNetwork(protec),
|
|
)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
ps, err := pubsub.NewGossipSub(ctx, host)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
pi, err := build.BuiltinBootstrap()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
if err := host.Connect(ctx, pi[0]); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
http.HandleFunc("/sub", handler(ps))
|
|
http.Handle("/", http.FileServer(rice.MustFindBox("townhall/build").HTTPBox()))
|
|
|
|
fmt.Println("listening on http://localhost:2975")
|
|
|
|
if err := http.ListenAndServe("0.0.0.0:2975", nil); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
type update struct {
|
|
From peer.ID
|
|
Update json.RawMessage
|
|
Time uint64
|
|
}
|
|
|
|
func handler(ps *pubsub.PubSub) func(w http.ResponseWriter, r *http.Request) {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
|
if r.Header.Get("Sec-WebSocket-Protocol") != "" {
|
|
w.Header().Set("Sec-WebSocket-Protocol", r.Header.Get("Sec-WebSocket-Protocol"))
|
|
}
|
|
|
|
conn, err := upgrader.Upgrade(w, r, nil)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
sub, err := ps.Subscribe(topic)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
fmt.Println("new conn")
|
|
|
|
for {
|
|
msg, err := sub.Next(r.Context())
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
//fmt.Println(msg)
|
|
|
|
if err := conn.WriteJSON(update{
|
|
From: peer.ID(msg.From),
|
|
Update: msg.Data,
|
|
Time: uint64(time.Now().UnixNano() / 1000_000),
|
|
}); err != nil {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|