最近系统开发中,新增了一个需求,要求客户登记以后,需要有一个对外的屏幕显示客户登记信息,方便客户确认个人信息及相关信息是否有误。在了解相关需求以后,我打算使用C#来配合实现双屏显示功能。作为一名java程序员,在使用C#开发过程中,感觉也挺有意思的,特此,简单记录一下实现思路。
org.springframework.boot</groupId>
spring-boot-starter-web</artifactId>
</dependency>
org.springframework.boot</groupId>
spring-boot-starter-test</artifactId>
test</scope>
</dependency>
server:
port: 8080
servlet:
context-path: /dsserver
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页title>
head>
<body>
<div>
<button onclick="openDSForm()">打开双屏显示button><br/>
<input id="content" type="text"/>
<button onclick="sendMessage()">发送消息button>
div>
body>
<script>
var spWebsocket;
function initSpWebsocket() {
if ('WebSocket' in window) {
spWebsocket = (spWebsocket && spWebsocket.readyState == spWebsocket.OPEN) ? spWebsocket : new WebSocket("ws://127.0.0.1:59999");
// 连接发生错误的回调方法
spWebsocket.onerror = function (err) {
console.log(err);
};
// 连接成功建立的回调方法
spWebsocket.onopen = function () {
console.log("spWebsocket打开关闭!");
};
// 接收到消息的回调方法
spWebsocket.onmessage = function (event) {
console.log(event.data);
}
// 连接关闭的回调方法
spWebsocket.onclose = function () {
console.log("spWebsocket连接关闭!");
}
} else {
alert("当前浏览器不支持websocket!");
}
}
function openDSForm() {
if(!(spWebsocket && spWebsocket.readyState == spWebsocket.OPEN)) {
initSpWebsocket();
}else {
spWebsocket.send("openDS");
}
}
function sendMessage() {
if(!(spWebsocket && spWebsocket.readyState == spWebsocket.OPEN)) {
initSpWebsocket();
}else {
var input = document.getElementById("content");
var functionName = "acceptMessage"; // 需要调用双屏显示页面的js中的方法名称
spWebsocket.send(functionName + "^" + input.value);
}
}
script>
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>双屏显示title>
head>
<body>
<div>
<h1 style="color: red">双屏显示内容:<label id="content" >label>h1>
div>
body>
<script>
function acceptMessage(msg) {
var input = document.getElementById("content");
input.innerText = msg;
}
script>
html>
开发中,我为了方便,并没有完全使用C#的窗口控件来做双屏显示客户端,而是只使用了C#窗口控件嵌套浏览器页面的做法,毕竟我对C#了解程度有限,开发时间也不充裕。
@Controller
public class TestController {
@GetMapping("/dsShow")
public String dsShow() {
return "doubleScreenShow.html";
}
}
以上,整个就是服务端的代码,只是用于演示,整个代码结构还是很简单的。
using CefSharp.WinForms;
using System.Windows.Forms;
namespace doublescreen_client
{
public partial class Form1 : Form
{
private ChromiumWebBrowser chrome = null;
public Form1(string url)
{
InitializeComponent();
// 初始化一个浏览器
if (url != null && !"".Equals(url))
{
chrome = new ChromiumWebBrowser(url)
{
Dock = DockStyle.Fill
};
this.Controls.Add(chrome);
}
this.Text = "双屏显示客户端";
this.ShowInTaskbar = false;// 不在工具栏显示图片
this.Hide(); // 隐藏窗口
}
private delegate void DeletegateShowDSForm();
// 显示窗口
public void DoShow()
{
if (this.InvokeRequired)
{
DeletegateShowDSForm dsf = new DeletegateShowDSForm(ShowDSFrom);
Invoke(dsf);
}
else
{
ShowDSFrom();
}
}
public void ShowDSFrom()
{
this.TopMost = true;// 窗口置顶
this.ShowInTaskbar = true;
this.WindowState = FormWindowState.Maximized;
this.Visible = true;
this.Activate();
this.Show();
}
public ChromiumWebBrowser GetBrowser()
{
return this.chrome;
}
}
}
using CefSharp.WinForms;
using Fleck;
using System;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
namespace doublescreen_client
{
static class Program
{
///
/// 应用程序的主入口点。
///
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
bool openFlag = CheckSoftWareOpenMore("doublescreen-client"); // 判断当前软件是否已经打开了
if (openFlag) // 如果已经打开了
{
DialogResult result = MessageBox.Show("你已经打开一个照相软件,请勿重复打开!", "提示:", MessageBoxButtons.OK, MessageBoxIcon.Warning);
if (result == DialogResult.OK)
{
System.Environment.Exit(0);
}
}
string serverUrl = "http://localhost:8080/dsserver/dsShow";
Form1 form = new Form1(serverUrl);
ChromiumWebBrowser chrome = form.GetBrowser();
// 创建一个websocket服务器,进行两个屏幕的通信
WebSocketServer server = new WebSocketServer("ws://127.0.0.1:59999" );
//出错后进行重启
server.RestartAfterListenError = true;
server.Start(socket =>
{
socket.OnOpen = () =>
{
};
socket.OnClose = () =>
{
};
socket.OnMessage = message =>
{
if (message == "ping...")
{
return;
}
string[] myParams = message.Split('^'); //获取参数值
if ("openDS".Equals(myParams[0]))
{
if (!form.Visible || FormWindowState.Minimized.Equals(form.WindowState))
{
form.DoShow();
}
return;
}
if (form.Visible)
{
string JSFunction = myParams[0] + "('" + myParams[1] + "')"; //拼接js方法
chrome.GetBrowser().MainFrame.EvaluateScriptAsync(JSFunction); // 调用网页中的js方法
}
};
});
Screen[] sc = Screen.AllScreens; // 获取所有屏幕
int showOnMonitor = 1; // 默认在附屏幕上显示
if (sc.Length == 1)
{
showOnMonitor = 0; // 如果只有一个屏幕就在主屏幕显示
}
form.StartPosition = FormStartPosition.Manual; // 设置手动指定窗口位置
form.Location = new Point(sc[showOnMonitor].Bounds.Left, sc[showOnMonitor].Bounds.Top); // 将窗口设置到另一个屏幕上
form.WindowState = FormWindowState.Minimized; // 默认开始最小化窗口
Application.Run(form);
}
// 判断程序是否已经打开
static bool CheckSoftWareOpenMore(string softwareName)
{
Process[] processes = Process.GetProcessesByName(softwareName);
if (processes.Length > 1)
{
return true;
}
else
{
return false;
}
}
}
}
这只是提供了一种实现双屏显示的思路,java部分的代码很简单,由于我对C#也不是很了解,代码风格应该也不好,大家只做参考,具体实现我就不做过多阐述,免得误人子弟,大家有兴趣看看注释。
实际业务肯定比这个复杂,原理大概就是这样,可以通过这个实现原理,把对人员的增删改查,和一些绑定信息的修改都实时的在对外的屏幕上向用户显示。