關(guān)鍵詞
- c#
- go
- 本地web
設(shè)計思路
用go語言編寫本地后臺
-
作用:
數(shù)據(jù)持久化耘柱。將數(shù)據(jù)存入sqlite數(shù)據(jù)庫腔长,還有數(shù)據(jù)的增刪改查葡缰,
本地web后端淆衷。監(jiān)聽本地1210端口缸榄,訪問本地1210端口可完成對數(shù)據(jù)的一系列操作
用c#語言編寫程序界面
-
作用:
管理后臺服務(wù)。啟動后臺祝拯,關(guān)閉后臺甚带。
與后臺交互。通過訪問本地端口鹿驼,實現(xiàn)對數(shù)據(jù)的一系列操作
代碼
后臺代碼實現(xiàn)
web.go
package main
import (
"database/sql"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
// "strconv"
// "time"
_ "github.com/mattn/go-sqlite3"
)
const (
TIMELIMIT = 10
)
type setting struct {
TIMELIMIT int
}
func main() {
var st setting
log.Println("start read setting")
st.readSetting()
log.Println("read setting is finish")
log.Printf("main: starting HTTP server")
httpServer()
// var srv *http.Server
// srv = new(http.Server)
// srv = httpServer()
// log.Printf("main: serving for " + strconv.Itoa(st.TIMELIMIT) + " seconds")
// time.Sleep(time.Duration(st.TIMELIMIT) * time.Second)
// log.Printf("main: stopping HTTP server")
// now close the server gracefully ("shutdown")
// timeout could be given instead of nil as a https://golang.org/pkg/context/
// if err := srv.Shutdown(nil); err != nil {
// panic(err) // failure/timeout shutting down the server gracefully
// }
// log.Printf("main: done. exiting")
}
func httpServer() {
htmlPath := "./index.html"
srv := &http.Server{Addr: ":1210"}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "http://localhost:1210")
var data []byte
var err error
reqURI := r.RequestURI
switch reqURI {
case "/":
data, err = readFile(htmlPath)
case "/data":
data, err = readSql()
default:
data, err = readFile("." + reqURI)
}
if err == nil {
w.Write(data)
}
})
if err := srv.ListenAndServe(); err != nil {
// cannot panic, because this probably is an intentional close
log.Printf("Httpserver: ListenAndServe() error: %s", err)
}
// go func() {
// if err := srv.ListenAndServe(); err != nil {
// // cannot panic, because this probably is an intentional close
// log.Printf("Httpserver: ListenAndServe() error: %s", err)
// }
// }()
// // returning reference so caller can call Shutdown()
// return srv
}
func (st *setting) readSetting() {
b, err := read("./setting.json")
checkErr(err)
if err := json.Unmarshal(b, st); err != nil {
panic(b)
}
}
func checkErr(err error) {
if err != nil {
panic(err)
}
}
type user struct {
id string `json:"id"`
place string `json:"place"`
account string `json:"account"`
password string `json:"password"`
note sql.NullString `json:"note"`
}
func (u *user) out() {
fmt.Println(u.id)
fmt.Println(u.place)
fmt.Println(u.account)
fmt.Println(u.password)
fmt.Println(u.note)
}
func readSql() ([]byte, error) {
return getJSON("select * from sercet")
}
func readFile(filepath string) ([]byte, error) {
return read(filepath)
}
func read(filepath string) ([]byte, error) {
f, err := os.Open(filepath)
if err != nil {
return nil, err
}
return ioutil.ReadAll(f)
}
func getJSON(sqlString string) ([]byte, error) {
db, err := sql.Open("sqlite3", "./sercet.db")
if err != nil {
return nil, err
}
stmt, err := db.Prepare(sqlString)
if err != nil {
return nil, err
}
defer stmt.Close() // defer的作用欲低,在打開stmt后,不管后面的代碼流程如何影響畜晰,它能夠被自動關(guān)閉。
rows, err := stmt.Query()
if err != nil {
return nil, err
}
defer rows.Close() // 同上
columns, err := rows.Columns() // 返回[]string, error
if err != nil {
return []byte(""), err
}
count := len(columns)
tableData := make([]map[string]interface{}, 0)
values := make([]interface{}, count)
valuePtrs := make([]interface{}, count)
for rows.Next() {
for i := 0; i < count; i++ {
valuePtrs[i] = &values[i] // 將引用放入數(shù)組中
}
rows.Scan(valuePtrs...) // 使用數(shù)組獲取結(jié)果瑞筐,"..."是
entry := make(map[string]interface{})
for i, col := range columns { // i是數(shù)字凄鼻,col是數(shù)組中對應(yīng)下標i的值
var v interface{}
val := values[i]
b, ok := val.([]byte) // 類型斷言(type assertion),簡單來說就是看val的類型是不是[]byte
if ok {
v = string(b)
} else {
v = val
}
entry[col] = v
}
tableData = append(tableData, entry)
}
return json.Marshal(tableData)
}
界面代碼實現(xiàn)
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PasswordManager
{
public partial class Form1 : Form
{
private Process p;
private progressForm pf;
public Form1()
{
InitializeComponent();
pf = new progressForm();
startWeb();
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
}
private void startWeb()
{
p = new Process();
p.StartInfo.FileName = Application.StartupPath + @"\web2\web.exe";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true; // 標準輸入流
p.StartInfo.RedirectStandardOutput = true; // 標準輸出流
p.StartInfo.RedirectStandardError = true; // 標準錯誤流
p.StartInfo.CreateNoWindow = true; // 創(chuàng)建沒有窗口
// 工作目錄 = 應(yīng)用啟動路徑
p.StartInfo.WorkingDirectory = Application.StartupPath + @"\web2\";
p.Start();
webBrowser1.Url = new Uri("http://localhost:1210/");
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
pf.Show();
pf.setValue(0);
Process[] processList = Process.GetProcesses();
foreach (Process p in processList)
{
if (p.ProcessName.ToLower() == "web")
{
pf.setValue(50);
p.Kill();
break;
}
}
pf.setValue(100);
pf.Close();
}
private void setValue(int n)
{
}
/// <summary>
/// 運行DOS命令
/// DOS關(guān)閉進程命令(ntsd -c q -p PID )PID為進程的ID
/// </summary>
/// <param name="command"></param>
/// <returns></returns>
private string RunCmd(string command)
{
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/c " + command;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
p.Start();
return p.StandardOutput.ReadToEnd();
}
}
}