Files
go3270/example3/example3.go
T
Matthew R. Wilson 5f2d7355e4 Non-screen-clearing update support
New ShowScreenOpts() function, which takes a new ScreenOpts struct, to control
various aspects of the ShowScreen behavior. This should now be used in favor of
the deprecated ShowScreen() and ShowScreenNoResponse() functions, and allows
for the additional of future options without needing to continue making new
functions or breaking the public API.
2025-04-12 16:56:24 -07:00

106 lines
2.7 KiB
Go

// This file is part of https://github.com/racingmars/go3270/
// Copyright 2020 by Matthew R. Wilson, licensed under the MIT license. See
// LICENSE in the project root for license information.
// This example demonstrates updating portions of the screen while waiting
// for a client response.
package main
import (
"fmt"
"net"
"time"
"github.com/racingmars/go3270"
)
var screen = go3270.Screen{
{Row: 0, Col: 35, Intense: true, Content: "3270 Clock"},
{Row: 1, Col: 0, Color: go3270.White,
Content: "------------------------------------------------------------------------------"},
{Row: 5, Col: 5, Color: go3270.Turquoise, Content: "The current UTC time is:"},
{Row: 5, Col: 30, Color: go3270.Yellow, Intense: true, Content: "XX:XX:XX"},
{Row: 22, Col: 0, Content: "PF3 Exit"},
}
var refresh = go3270.Screen{
screen[3], // Copy the time field that we want to update
}
func main() {
ln, err := net.Listen("tcp", ":3270")
if err != nil {
panic(err)
}
fmt.Println("LISTENING ON PORT 3270 FOR CONNECTIONS")
fmt.Println("Press Ctrl-C to end server.")
for {
conn, err := ln.Accept()
if err != nil {
panic(err)
}
go handle(conn)
}
}
// handle is the handler for individual user connections.
func handle(conn net.Conn) {
defer conn.Close()
// Always begin new connection by negotiating the telnet options
go3270.NegotiateTelnet(conn)
// First, let's send the initial screen and wait forever for the user to
// press PF3, and when we get it, send a message on the done channel.
done := func() chan bool {
done := make(chan bool)
// This will run in a goroutine so it can block waiting for the
// response, while the rest of the code below (which refreshes the
// screen every second) can continue to run.
go func() {
// Loop forever, sending the background screen until user exits.
for {
screen[3].Content = time.Now().UTC().Format("15:04:05")
response, err := go3270.ShowScreenOpts(screen, nil, conn,
go3270.ScreenOpts{CursorRow: 23, CursorCol: 0})
if err != nil {
// User dropped connection, maybe? We'll end things.
done <- true
return
}
if response.AID == go3270.AIDPF3 {
// User wants to quit.
done <- true
return
}
}
}()
return done
}()
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for {
select {
case <-done:
// User pressed PF3 (or we need to quit for some other reason)
return
case <-ticker.C:
// Send the updated time, without clearing the screen
refresh[0].Content = time.Now().UTC().Format("15:04:05")
_, err := go3270.ShowScreenOpts(refresh, nil, conn,
go3270.ScreenOpts{NoClear: true, NoResponse: true})
if err != nil {
// Bail out
return
}
}
}
}