Exemple #1
0
func (c *SessionClient) dialWebsocketJS(service string, action string) (net.Conn, error) {
	var wsurl string

	if c.WSURL == "" {
		burl, err := url.Parse(c.APIURL)
		if err != nil {
			return nil, err
		}
		if burl.Scheme == "https" {
			burl.Scheme = "wss"
		} else {
			burl.Scheme = "ws"
		}

		wsurl = burl.String()
	} else {
		wsurl = c.WSURL
	}

	wsurl += fmt.Sprintf(c.Prefix+"/session/%s/conn/%s%s/websocket",
		c.ID,
		service,
		action)

	return jswebsocket.Dial(wsurl)
}
Exemple #2
0
func main() {
	if true {
		wsBaseURL := fmt.Sprintf("ws://%s:%s/ws/", location.Get("hostname"), location.Get("port"))
		ws, err := websocket.Dial(wsBaseURL + "rpc/foo")
		if err != nil {
			log.Fatal("Dial ", err)
			return
		}
		l := &Listener{}
		rpc = weeb.NewRpc(ws, l)
		l.rpc = rpc

		// go HelloRpcClient(rpc)
		go rpc.Serve()
	}

	if false {
		fu()
	}

	jq().Ready(func() {
		screenPixelsPerPoint = findScreenPixelsPerPoint()
		doc.AddEventListeners(document)
		jqBind(jq(":root"))
	})
}
Exemple #3
0
//New connects websocket and returns Browser obj.
func New(dest string, str interface{}) (*Browser, error) {
	var err error
	b := &Browser{}
	if err := rpc.Register(str); err != nil {
		return nil, err
	}
	b.s, err = websocket.Dial("ws://" + dest + "/ws-client") // Blocks until connection is established
	if err != nil {
		return nil, err
	}
	log.Println("ws-client connected")
	go jsonrpc.ServeConn(b.s)

	b.c, err = websocket.Dial("ws://" + dest + "/ws-server") // Blocks until connection is established
	if err != nil {
		return nil, err
	}
	log.Println("client connected")
	b.Client = jsonrpc.NewClient(b.c)
	return b, nil
}
Exemple #4
0
func rpcInit() error {
	conn, err := websocket.Dial("ws://" + js.Global.Get("location").Get("host").String() + "/rpc")
	if err != nil {
		return err
	}
	conn.WebSocket.Call("addEventListener", "close", func(*js.Object) {
		xjs.RemoveChildren(xdom.Body()).AppendChild(xjs.SetInnerText(xdom.H1(), "Connection Lost"))
	}, false)
	dom.GetWindow().AddEventListener("beforeunload", false, func(dom.Event) {
		switch conn.ReadyState {
		case websocket.Connecting, websocket.Open:
			conn.Close()
		}
	})
	RPC = jRPC{jsonrpc.NewClient(conn)}
	return nil
}
Exemple #5
0
func connect(wsEndpoint string) *websocket.Conn {
	count := 0

	ticker := time.NewTicker(time.Duration(1) * time.Second)
	defer ticker.Stop()

	// connect
	for {
		count++

		console.Log(fmt.Printf("trying to connect to server at %s, attempt %d", wsEndpoint, count))

		conn, err := websocket.Dial(wsEndpoint) // Blocks until connection is established
		if err == nil {
			return conn
		}
		console.Error(err.Error())

		<-ticker.C
	}
}
Exemple #6
0
func main() {
	wsBaseURL := getWSBaseURL()

	qunit.Module("websocket.WebSocket")
	qunit.Test("Invalid URL", func(assert qunit.QUnitAssert) {
		qunit.Expect(1)

		ws, err := websocket.New("blah://blah.example/invalid")
		if err == nil {
			ws.Close()
			assert.Ok(false, "Got no error, but expected an invalid URL error")
			return
		}

		assert.Ok(true, fmt.Sprintf("Received an error: %s", err))
	})
	qunit.AsyncTest("Immediate close", func() interface{} {
		qunit.Expect(2)

		ws, err := websocket.New(wsBaseURL + "immediate-close")
		if err != nil {
			qunit.Ok(false, fmt.Sprintf("Error opening WebSocket: %s", err))
			qunit.Start()
			return nil
		}

		ws.AddEventListener("open", false, func(ev *js.Object) {
			qunit.Ok(true, "WebSocket opened")
		})

		ws.AddEventListener("close", false, func(ev *js.Object) {
			const (
				CloseNormal            = 1000
				CloseNoReasonSpecified = 1005 // IE10 hates it when the server closes without sending a close reason
			)
			closeEvent := dom.WrapEvent(ev).(*dom.CloseEvent)
			if closeEvent.Code != CloseNormal && closeEvent.Code != CloseNoReasonSpecified {
				qunit.Ok(false, fmt.Sprintf("WebSocket close was not clean (code %d)", closeEvent.Code))
				qunit.Start()
				return
			}
			qunit.Ok(true, "WebSocket closed")
			qunit.Start()
		})

		return nil
	})

	qunit.Module("websocket.Conn")
	qunit.AsyncTest("Immediate close", func() interface{} {
		go func() {
			defer qunit.Start()

			ws, err := websocket.Dial(wsBaseURL + "immediate-close")
			if err != nil {
				qunit.Ok(false, fmt.Sprintf("Error opening WebSocket: %s", err))
				return
			}

			qunit.Ok(true, "WebSocket opened")

			_, err = ws.Read(nil)
			if err == io.EOF {
				qunit.Ok(true, "Received EOF")
			} else if err != nil {
				qunit.Ok(false, fmt.Sprintf("Unexpected error in second read: %s", err))
			} else {
				qunit.Ok(false, "Expected EOF in second read, got no error")
			}
		}()

		return nil
	})
	qunit.AsyncTest("Failed open", func() interface{} {
		go func() {
			defer qunit.Start()

			ws, err := websocket.Dial(wsBaseURL + "404-not-found")
			if err == nil {
				ws.Close()
				qunit.Ok(false, "Got no error, but expected an error in opening the WebSocket.")
				return
			}

			qunit.Ok(true, fmt.Sprintf("WebSocket failed to open: %s", err))
		}()

		return nil
	})
	qunit.AsyncTest("Binary read", func() interface{} {
		qunit.Expect(3)

		go func() {
			defer qunit.Start()

			ws, err := websocket.Dial(wsBaseURL + "binary-static")
			if err != nil {
				qunit.Ok(false, fmt.Sprintf("Error opening WebSocket: %s", err))
				return
			}

			qunit.Ok(true, "WebSocket opened")

			var expectedData = []byte{0x00, 0x01, 0x02, 0x03, 0x04}

			receivedData := make([]byte, len(expectedData))
			n, err := ws.Read(receivedData)
			if err != nil {
				qunit.Ok(false, fmt.Sprintf("Error in first read: %s", err))
				return
			}
			receivedData = receivedData[:n]

			if !bytes.Equal(receivedData, expectedData) {
				qunit.Ok(false, fmt.Sprintf("Received data did not match expected data. Got % x, expected % x.", receivedData, expectedData))
			} else {
				qunit.Ok(true, fmt.Sprintf("Received data: % x", receivedData))
			}

			_, err = ws.Read(receivedData)
			if err == io.EOF {
				qunit.Ok(true, "Received EOF")
			} else if err != nil {
				qunit.Ok(false, fmt.Sprintf("Unexpected error in second read: %s", err))
			} else {
				qunit.Ok(false, "Expected EOF in second read, got no error")
			}
		}()

		return nil
	})
	qunit.AsyncTest("Timeout", func() interface{} {
		qunit.Expect(2)

		go func() {
			defer qunit.Start()

			ws, err := websocket.Dial(wsBaseURL + "wait-30s")
			if err != nil {
				qunit.Ok(false, fmt.Sprintf("Error opening WebSocket: %s", err))
				return
			}

			qunit.Ok(true, "WebSocket opened")

			start := time.Now()
			ws.SetReadDeadline(start.Add(1 * time.Second))

			_, err = ws.Read(nil)
			if err != nil && err.Error() == "i/o timeout: deadline reached" {
				totalTime := time.Now().Sub(start)
				if totalTime < 750*time.Millisecond {
					qunit.Ok(false, fmt.Sprintf("Timeout was too short: Received timeout after %s", totalTime))
					return
				}
				qunit.Ok(true, fmt.Sprintf("Received timeout after %s", totalTime))
			} else if err != nil {
				qunit.Ok(false, fmt.Sprintf("Unexpected error in read: %s", err))
			} else {
				qunit.Ok(false, "Expected timeout in read, got no error")
			}
		}()

		return nil
	})
}
Exemple #7
0
func transferFile(typeName, method string, typeID uint8, o *overlay.Overlay) dom.Node {
	name := xform.InputText("name", "")
	url := xform.InputRadio("url", "switch", true)
	upload := xform.InputRadio("upload", "switch", false)
	fileI := xform.InputUpload("")
	urlI := xform.InputURL("", "")
	s := xform.InputSubmit(method)

	name.Required = true

	typeFunc := func(dom.Event) {
		if url.Checked {
			urlI.Style().RemoveProperty("display")
			fileI.Style().SetProperty("display", "none", "")
			urlI.Required = true
			fileI.Required = false
			fileI.SetID("")
			urlI.SetID("file")
		} else {
			fileI.Style().RemoveProperty("display")
			urlI.Style().SetProperty("display", "none", "")
			fileI.Required = true
			urlI.Required = false
			urlI.SetID("")
			fileI.SetID("file")
		}
	}

	typeFunc(nil)

	url.AddEventListener("change", false, typeFunc)
	upload.AddEventListener("change", false, typeFunc)

	f := xjs.AppendChildren(xdom.Form(), xjs.AppendChildren(xdom.Fieldset(),
		xjs.SetInnerText(xdom.Legend(), method+" "+typeName),
		xform.Label(typeName+" Name", "name"),
		name,
		xdom.Br(),

		xform.Label("URL", "url"),
		url,
		xdom.Br(),

		xform.Label("Upload", "upload"),
		upload,
		xdom.Br(),

		xform.Label("File", "file"),

		fileI,
		urlI,

		xdom.Br(),
		s,
	))

	s.AddEventListener("click", false, func(e dom.Event) {
		if name.Value == "" {
			return
		}
		if url.Checked {
			if urlI.Value == "" {
				return
			}
		} else if len(fileI.Files()) != 1 {
			return

		}
		s.Disabled = true
		name.Disabled = true
		url.Disabled = true
		upload.Disabled = true
		fileI.Disabled = true
		urlI.Disabled = true
		e.PreventDefault()
		go func() {
			d := xdom.Div()
			uo := overlay.New(d)
			uo.OnClose(func() {
				o.Close()
			})
			xjs.Body().AppendChild(uo)
			status := xdom.Div()
			d.AppendChild(xjs.SetInnerText(status, "Transferring..."))
			conn, err := websocket.Dial("ws://" + js.Global.Get("location").Get("host").String() + "/transfer")
			if err != nil {
				xjs.SetInnerText(status, err.Error())
				return
			}
			defer conn.Close()
			w := byteio.StickyWriter{Writer: byteio.LittleEndianWriter{Writer: conn}}
			r := byteio.StickyReader{Reader: byteio.LittleEndianReader{Reader: conn}}

			pb := progress.New(color.RGBA{255, 0, 0, 0}, color.RGBA{0, 0, 255, 0}, 400, 50)
			d.AppendChild(pb)

			if url.Checked {
				w.WriteUint8(typeID << 1)
				data.WriteString(&w, urlI.Value)
				length := int(r.ReadInt32())
				total := 0
				for total < length {
					switch v := r.ReadUint8(); v {
					case 1:
						i := int(r.ReadInt32())
						total += i
						pb.Percent(100 * total / length)
					default:
						xjs.SetInnerText(status, ReadError(&r).Error())
						return
					}
				}
			} else {
				f := files.NewFileReader(files.NewFile(fileI.Files()[0]))
				l := f.Len()
				if l == 0 {
					xjs.SetInnerText(status, "Zero-length file")
					return
				}
				w.WriteUint8(typeID<<1 | 1)
				w.WriteInt32(int32(l))
				io.Copy(&w, pb.Reader(f, l))
			}

			d.RemoveChild(pb)
			xjs.SetInnerText(status, "Checking File")

			data.WriteString(&w, name.Value)

			var ctx *dom.CanvasRenderingContext2D

			for {
				switch v := r.ReadUint8(); v {
				case 0:
					if r.Err != nil {
						xjs.SetInnerText(status, r.Err.Error())
					} else {
						xjs.SetInnerText(status, ReadError(&r).Error())
					}
					return
				case 1:
					files := make([]xform.Option, r.ReadInt16())
					for i := range files {
						files[i] = xform.Option{
							Value: strconv.Itoa(i),
							Label: data.ReadString(&r),
						}
					}
					j := xform.SelectBox("files", files...)
					sel := xjs.SetInnerText(xdom.Button(), "Select")
					fo := overlay.New(xjs.AppendChildren(xdom.Div(), xjs.AppendChildren(xdom.Fieldset(),
						xjs.SetInnerText(xdom.Legend(), "Please select the "+typeName+" file"),
						xform.Label("File", "files"),
						j,
						xdom.Br(),
						sel,
					)))
					c := make(chan int16, 0)
					done := false
					fo.OnClose(func() {
						if !done {
							done = true
							c <- -1
						}
					})
					sel.AddEventListener("click", false, func(dom.Event) {
						if !done {
							done = true
							v, err := strconv.Atoi(j.Value)
							if err != nil {
								v = -1
							}
							c <- int16(v)
							fo.Close()
						}
					})
					xjs.Body().AppendChild(fo)
					w.WriteInt16(<-c)
					close(c)
				case 2:
					w := r.ReadInt32()
					h := r.ReadInt32()
					canvas := xdom.Canvas()
					canvas.Width = int(w) * 8
					canvas.Height = int(h) * 8
					d.AppendChild(canvas)
					ctx = canvas.GetContext2d()
					ctx.Scale(8, 8)
				case 3:
					xjs.SetInnerText(status, data.ReadString(&r))
				case 4:
					x := r.ReadInt32()
					y := r.ReadInt32()
					red := r.ReadUint8()
					green := r.ReadUint8()
					blue := r.ReadUint8()
					alpha := r.ReadUint8()
					ctx.FillStyle = "rgba(" + strconv.Itoa(int(red)) + ", " + strconv.Itoa(int(green)) + ", " + strconv.Itoa(int(blue)) + ", " + strconv.FormatFloat(float64(alpha)/255, 'f', -1, 32) + ")"
					ctx.FillRect(int(x), int(y), 1, 1)
				case 255:
					uo.Close()
					return
				}
			}

		}()
	})
	return f
}
Exemple #8
0
func serverConsole(s data.Server) func(dom.Element) {
	return func(c dom.Element) {
		log := xform.TextArea("log", "")
		log.ReadOnly = true
		command := xform.InputText("command", "")
		command.Required = true
		send := xform.InputSubmit("Send")
		c.AppendChild(xjs.AppendChildren(xdom.Form(), xjs.AppendChildren(xdom.Fieldset(),
			xjs.SetInnerText(xdom.Legend(), "Console"),
			xform.Label("Log", ""), log, xdom.Br(),
			xform.Label("Command", "command"), command, send,
		)))
		if s.State == data.StateStopped {
			send.Disabled = true
			command.Disabled = true
		} else {
			send.AddEventListener("click", false, func(e dom.Event) {
				if command.Value == "" {
					return
				}
				e.PreventDefault()
				send.Disabled = true
				cmd := command.Value
				log.Value += "\n>" + cmd + "\n"
				log.Set("scrollTop", log.Get("scrollHeight"))
				command.Value = ""
				go func() {
					err := RPC.WriteCommand(s.ID, cmd)
					if err != nil {
						xjs.Alert("Error sending command: %s", err)
						return
					}
					send.Disabled = false
				}()
			})
		}
		go func() {
			conn, err := websocket.Dial("ws://" + js.Global.Get("location").Get("host").String() + "/console")
			if err != nil {
				xjs.Alert("Failed to connect to console: %s", err)
				return
			}
			defer conn.Close()
			w := byteio.StickyWriter{Writer: byteio.LittleEndianWriter{Writer: conn}}
			r := byteio.StickyReader{Reader: byteio.LittleEndianReader{Reader: conn}}
			updateStop := make(chan struct{})
			registerUpdateStopper(c, updateStop)
			done := false
			go func() {
				<-updateStop
				done = true
				conn.Close()
			}()
			w.WriteInt32(int32(s.ID))
			for {
				state := r.ReadUint8()
				switch state {
				case 0:
					if !done {
						err := ReadError(&r)
						if r.Err != nil {
							err = r.Err
						}
						log.Value += "\n\nError reading from console: " + err.Error()
						log.Set("scrollTop", log.Get("scrollHeight"))
					}
					return
				case 1:
					log.Value += data.ReadString(&r)
					log.Set("scrollTop", log.Get("scrollHeight"))
				}
			}
		}()
	}
}
Exemple #9
0
func Start() error {

	loc := dom.GetWindow().Location()
	addr := fmt.Sprintf("ws://%s:%s/_rpc", loc.Hostname, loc.Port)
	ws, err := websocket.Dial(addr)
	if err != nil {
		return kerr.Wrap("HNQFLPFAJD", err)
	}

	app := &stores.App{
		Conn: connection.New(rpc.NewClient(ws)),
		Fail: make(chan error),
	}

	// We parse the info attribute from the body tag
	info, err := getInfo(getRawInfo())
	if err != nil {
		return kerr.Wrap("MGLVIQIDDY", err)
	}

	var ctx context.Context
	ctx = context.Background()
	ctx = envctx.NewContext(ctx, &envctx.Env{Path: info.Path, Aliases: info.Aliases})
	ctx = sysctx.NewContext(ctx)
	ctx = jsonctx.AutoContext(ctx)
	ctx = stores.NewContext(ctx, app)
	ctx = clientctx.NewContext(ctx)

	app.Init(ctx)

	// Don't do this. Implement the Editable interface instead. We can't do
	// this for system types so we use this method instead.
	editors.Register(ctx)

	if _, err := registerTypes(ctx, info.Path, info.Imports); err != nil {
		return kerr.Wrap("MMJDDOBAUK", err)
	}

	p := views.NewPage(ctx)
	vecty.RenderBody(p)

	// TODO: work out why I can't seem to call this without using eval
	js.Global.Get("window").Call("eval", "Split(['#tree', '#main'], {sizes:[25, 75]});")

	app.Dispatch(&actions.InitialState{
		Info: info,
	})

	go func() {
		err, open := <-app.Fail
		if !open {
			// Channel has been closed, so app should gracefully exit.
			fmt.Println("Server disconnected")
		} else {
			// Error received, so app should display error.
			fmt.Println(err.Error())
		}
	}()

	return nil
}
func run() error {
	webSocketClosed := false
	ws, err := websocket.Dial(js.Global.Get("WebSocketAddress").String())
	if err != nil {
		return err
	}
	defer ws.Close()
	ws.AddEventListener("close", false, func(_ *js.Object) {
		webSocketClosed = true
	})
	enc := json.NewEncoder(ws)
	dec := json.NewDecoder(ws)

	// Clear all markers (possibly left over from previous connection).
	for _, marker := range markers {
		marker.RemoveFromMap(mapView)
	}

	var bounds *mapview.LatLngBounds
	var lat, lng float64
	var accuracy float64
	foundLocation := false

	shareIcon := document.GetElementByID("share-icon").(*dom.HTMLImageElement)
	shareIcon.AddEventListener("click", false, func(event dom.Event) {
		event.PreventDefault()
		shareBox := document.GetElementByID("share-box").(*dom.HTMLInputElement)
		shareBox.Style().SetProperty("display", "initial", "")
		shareBox.Focus()
		shareBox.Select()
		shareBox.Value = dom.GetWindow().Location().Href

		shareIcon.Style().SetProperty("display", "none", "")

		shareBox.AddEventListener("blur", false, func(event dom.Event) {
			event.PreventDefault()
			shareBox.Style().SetProperty("display", "none", "")
			shareIcon.Style().SetProperty("display", "initial", "")
		})
	})

	go func() {
		for {
			if webSocketClosed {
				break
			}

			time.Sleep(time.Second)

			if !foundLocation {
				continue
			}

			clientState := common.ClientState{
				Name:     document.GetElementByID("message").(*dom.HTMLInputElement).Value,
				Lat:      lat,
				Lng:      lng,
				Accuracy: accuracy,
			}

			err = enc.Encode(clientState)
			if err != nil {
				log.Println("enc.Encode:", err)
				break
			}
		}
	}()

	mapView.OnLocFound(func(loc *js.Object) {
		document.GetElementByID("spinner-container").(dom.HTMLElement).Style().SetProperty("display", "none", "")

		foundLocation = true
		latlng := loc.Get("latlng")
		lat = latlng.Get("lat").Float()
		lng = latlng.Get("lng").Float()
		accuracy = loc.Get("accuracy").Float()
	})

	mapView.StartLocate()

	for {
		var msg common.ServerUpdate
		originalIds := make(map[int64]struct{})

		for k := range markers {
			originalIds[k] = struct{}{}
		}

		err = dec.Decode(&msg)
		if err != nil || webSocketClosed {
			log.Println("dec.Decode:", err)
			break
		}

		for i, clientState := range msg.Clients {
			if markers[clientState.Id] == nil {
				markers[clientState.Id] = mapView.AddMarkerWithMessage(clientState.Lat, clientState.Lng, clientState.Accuracy, clientState.Name)
			} else {
				markers[clientState.Id].SetLatLng(clientState.Lat, clientState.Lng)
				markers[clientState.Id].SetMessage(clientState.Name)
				markers[clientState.Id].SetAccuracy(clientState.Accuracy)
				delete(originalIds, clientState.Id)
			}

			if i == 0 {
				bounds = mapview.NewLatLngBounds(
					mapview.NewLatLng(clientState.Lat, clientState.Lng),
					mapview.NewLatLng(clientState.Lat, clientState.Lng))
			} else {
				bounds.Extend(mapview.NewLatLng(clientState.Lat, clientState.Lng))
			}
		}

		for key := range originalIds {
			markers[key].RemoveFromMap(mapView)
		}

		if bounds != nil {
			bounds.Pad(0.10)
			mapView.FitBounds(bounds)
		}

		log.Printf("%#v\n", msg)
	}

	mapView.StopLocate()

	return nil
}