go+iris+jwt+mysql+xorm+viper는 로그인, 등록, 개인 채팅, 그룹 채팅 기능을 갖춘 iris 프로젝트를 위한 실용적이고 간단한 채팅방입니다.
먼저 이 문서 아래에 있는 프런트 엔드 소개를 살펴보고 작동 방법을 알아보세요(에너지가 제한되어 UI가 특별히 사용자 친화적이지 않습니다).
데모주소에 접속하세요. 위 작은 아이콘의 상태가 정상이라면 휴면상태로 진입하여 몇초간 기다려야 접속이 가능합니다.
현재 프로젝트는 mysql 관련 적응만 작성하고 있는데, xorm을 사용하면 다른 데이터베이스도 지원하기 어렵지 않습니다. 할 필요는 없지만, 하하하, 직접 실행하기에는 너무 게으른 경우 한번 살펴보세요. 데모 URL에 관심이 있다면 현재 mysql을 사용하는 사람은 없습니다.
원래는 sqlite를 지원해서 데이터베이스 매개변수를 설정할 필요가 없도록 하고 싶었는데, Windows에서 sqlite를 컴파일하려면 gcc 환경을 설정해야 한다는 점을 고려하면 더 번거롭지만 빠른 시작 효과도 없고 단순히 완전하지도 않습니다. 이므로 다른 데이터베이스는 당분간 지원되지 않습니다(언젠가 시간이 나면 더 추가하겠습니다).
따라서 프로젝트에서는 다음 매개변수만 구성하면 됩니다.
git clone https://github.com/JabinGP/demo-chatroom.git
cd demo-chatroom
// 复制config.toml.example 为 config.toml 并填写数据库信息,或者可选修改端口号
go run main.go
기본값은 포트 8888입니다. 시작 후 http://localhost:8888
에 액세스합니다.
리액트를 사용했지만 UI 프레임워크를 사용하지 않아서 작은 디테일이 잘 구현되지 않는 경우가 많습니다. 컴퓨터를 열면 f12가 열리게 됩니다. .. 초점은 후자에 있습니다.
채팅창에서는 창이 자동으로 하단으로 스크롤되도록 설정했지만 API는 React에서 제공하며 많은 브라우저에서 호환되지 않는 것으로 나타났습니다. 이 문제는 Chrome 브라우저를 사용하여 해결할 수 있습니다.
등록 후 수동으로 돌아가서 로그인을 선택하세요. 메시지 상자의 빨간색 이름은 공개 대화용이고, 회색 이름은 비공개 채팅용입니다. 지정하지 않을 경우 기본값은 다음과 같습니다. 공개 연설을 지정한 후에는 해당 사용자만 정보를 볼 수 있습니다.
사용자 이름은 파란색 상자에 표시됩니다. 직접 로그아웃하려면 클릭하세요.
API 형식은 Restful 설계를 기반으로 하며, 로그인 기능은 jwt를 사용하여 완성됩니다. 많은 인터페이스에서 로그인 상태가 필요하며, 요청 시 JWT를 휴대해야 합니다. 추가로 golang iris의 jwt practice를 참조하세요. 테스트에 편리합니다. JWT 발급 유효 시간은 20분으로만 설정되어 있으므로 다시 로그인해야 합니다.
API 요청 형식은 일반 인터페이스와 동일합니다. Get은 Params를 사용하고 Post, Put, Delete 등은 Body에서 Json을 사용하여 매개변수를 전달합니다.
반환 형식은 꽤 논란의 여지가 있습니다. 일부 사람들은 전체 200 http 상태 코드를 사용하고 오류를 식별하기 위해 다음과 같은 코드를 추가하는 것을 옹호합니다.
// 注册错误时
// http status 200
{
"code" : 40001 ,
"msg" : "注册用户名非法"
}
// 注册成功时
// http status 200
{
"code" : 200 ,
"msg" : "成功" ,
"data" : {
"username" : " JabinGP " ,
"id" : 3
}
}
다른 사람들은 오류를 표시하기 위해 전체 http 상태 코드 사용을 옹호합니다.
// 注册错误时
// http status 400
{
"msg" : "注册用户名非法"
}
// 注册成功时
// http status 200
{
"username" : " JabinGP " ,
"id" : 3
}
실제로 위의 두 가지 접근 방식에는 모두 장단점이 있습니다.
위의 상황을 바탕으로 두 가지를 결합하겠습니다.
성공하면 http 상태 코드 200을 반환합니다.
// 注册成功时
// http status 200
{
"username" : " JabinGP " ,
"id" : 3
}
실패가 발생하면 일반적으로 사용되는 여러 가지 오류 표현 상태 코드인 400(요청 오류), 500(서버 내부 오류), 404(찾을 수 없음), 401(인증 실패)을 선택하여 대략적으로 오류를 분류한 후 반환합니다. 코드, 메시지 및 데이터의 세부 정보를 사용하여 자세한 오류 원인을 나타냅니다.
// 注册失败
// http status 400
{
"code" : 6 ,
"msg" : "数据检验失败" ,
"detail" : "用户名已存在"
}
// 登录失效
// http status 401
{
"code" : 8 ,
"msg" : "未认证登录" ,
"detail" : " Token is expired "
}
이 조합 후에는 성공적인 콜백이 성공하며 res.data.data를 작성할 필요가 없습니다. 오류 콜백은 http 상태 코드로 판단할 수 있는 오류만 처리하며 추가 코딩, msg 및 세부 정보가 가능합니다. . 오류를 처리합니다.
API 목록은 다음과 같습니다. localhost를 mike.jabingp.cn으로 바꾸거나 데모 백엔드에 직접 요청할 수 있습니다.
기능 | 요청 방법 | 주소 |
---|---|---|
로그인 토큰 받기 | 우편 | http://localhost:8888/v1/로그인 |
사용자 찾기 | 얻다 | http://localhost:8888/v1/사용자 |
등록하다 | 우편 | http://localhost:8888/v1/사용자 |
사용자가 직접 정보를 수정합니다. | 놓다 | http://localhost:8888/v1/사용자 |
사용자가 메시지를 보냅니다. | 우편 | http://localhost:8888/v1/메시지 |
사용자가 정보를 얻습니다. | 얻다 | http://localhost:8888/v1/메시지 |
사용자가 토큰 정보를 얻습니다. | 얻다 | http://localhost:8888/v1/token/info |
자세한 요청 매개변수는 데모 채팅룸의 postman-api 문서에서 볼 수 있습니다.
또는 소스 코드를 보면 요청 매개변수는 model/reqo
에서 볼 수 있고 응답 매개변수는 model/reso
채팅 기능으로는 AJAX가 최선의 선택은 아니지만 WebSocket이 더 좋지만 AJAX를 사용하라는 요청을 받아 후자를 선택하지 않았습니다.
프로젝트의 프런트 엔드는 데모로만 사용되기 때문에 비교적 간단합니다.
영어 실력도 별로 좋지 않고, 입력 방식을 바꾸기엔 너무 게으른 탓에 코드 주석도 영어로 되어 있습니다.
웹 프로젝트를 개발하기 위해 go를 사용한 것은 이번이 처음이고, 프론트엔드를 작성하기 위해 React를 사용한 것도 처음입니다. 소스코드를 넣어서 가독성을 위해 프로젝트를 컴파일하고 에셋 폴더에 넣어두었습니다. 매우 열악하지만 백엔드와 함께 시작할 수 있어서 별도로 프런트엔드를 시작할 필요가 없어 보기가 더 편리합니다. 효과. 아직 시간이 있다면 모든 사람이 참고할 수 있도록 네이티브 버전으로 미니멀한 버전을 작성하는 것을 고려해 보겠습니다.
데이터베이스를 운영하기 위해 ORM을 처음 사용하는데, SQL을 직접 작성하는 것이 더 좋을 것 같고, 오랫동안 문서를 읽어도 해결책을 찾을 수 없습니다. 나중에 SQLX를 사용하여 재구성하는 것을 고려해 보겠습니다.
최근에 Go에 더 관심을 가지게 되었는데, 간단한 채팅방을 작성하라는 과제를 받았는데, 현재 iris에서는 프로젝트 실습이 거의 없고 HelloWorld 수준의 예제만 있는 것을 보고 Go를 사용하기로 했습니다. 물론, 프로젝트 구조를 설계하는 방법은 전적으로 저의 제한된 개발 경험을 바탕으로 한 것이므로 불합리한 부분에 대해서는 소중한 의견 부탁드립니다.
이 프로젝트에는 다음과 같은 요구 사항이 있습니다.
이번에는 JWT
사용하여 로그인 기능을 구현합니다. JWT
와 Session
의 장점과 단점은 자세히 설명하지 않습니다.
AJAX 기반은 모든 프런트엔드 및 백엔드 분리 프로젝트에 필수이므로 이 기능은 너무 많이 논의되지 않습니다. 여기서 초점은 새로 고침이 없다는 것입니다.
사용자의 작업 논리는 채팅방에서 데이터를 보낸 다음 데이터가 전송되는 것입니다. 채팅 인터페이스는 자체적으로 보낸 데이터를 표시하고 다른 사람이 보낸 데이터를 실시간으로 업데이트해야 합니다.
프런트엔드와 백엔드는 AJAX를 통해 통신합니다. 프런트엔드에서 보내는 데이터와 백엔드에서 보내는 데이터는 다음과 같이 표현할 수 있습니다.
여기서 문제가 무엇입니까? 문제는 프런트 엔드는 요청을 적극적으로 시작할 수만 있고 백 엔드는 요청을 수락할 수만 있다는 것입니다. 즉, 최신 메시지는 백엔드에서 프런트엔드로 실시간으로 전송될 수 없습니다. 최신 메시지는 먼저 백엔드에 저장된 다음 백엔드가 데이터를 반환하기 전에 프런트엔드가 요청을 시작할 때까지 기다릴 수 있습니다.
백엔드에는 메시지를 프런트엔드에 적극적으로 푸시할 수 있는 기능이 없기 때문에 사용자가 최신 데이터를 얻을 수 있는 솔루션은 프런트엔드가 타이머를 설정每隔一段比较短的时间就请求一次后台接口(轮询)
입니다. 데이터는 지속적으로 업데이트될 수 있습니다.
프런트 엔드는 AJAX를 사용하여 정기적으로 백그라운드 인터페이스를 폴링하여 최신 데이터를 얻기로 결정했습니다. 폴링 간격은小于1s
이렇게 빈번한 요청으로 인해 백엔드는 매번 모든 데이터를 전송해서는 안 됩니다. 하나는 데이터 크기로 인한 네트워크 전송 효율성과 트래픽 비용입니다. 새로운 데이터에 대한 프런트 엔드의 판단은 프런트 엔드가 매번 수신하지 못한 데이터를 백엔드가 반환해야 함을 의미합니다. 문제는 프런트 엔드가 어떤 정보를 받았는지 어떻게 백엔드가 알 수 있는가입니다.
이를 위해서는 메시지의自增主键
를 사용해야 합니다. 기본 키는 요청을 할 때마다 프런트 엔드에서 수신한最后的消息的主键
전달하면 됩니다. 반복하고 자동 증가하면 비율을 쉽게 알 수 있습니다. 기본 키가 큰 데이터는 프런트 엔드가 아직 수신하지 못한 데이터입니다.
언어
액자
데이터 저장
기술
Xorm 데이터베이스 ORM 프레임워크의 사용으로 인해 다음 테이블이 자동으로 생성되고
xxxxxx_at
필드와 함께 제공됩니다.
위의 요구사항을 바탕으로 users
와 messages
두 개의 테이블을 설계했습니다.
주요 분야
데이터베이스 테이블 구조
필드 | 유형 | 널 | 열쇠 | 기본 | 추가의 |
---|---|---|---|---|---|
ID | 비긴트(20) | 아니요 | PRI | NULL | 자동 증가 |
사용자 이름 | varchar(255) | 예 | NULL | ||
비밀번호 | varchar(255) | 예 | NULL | ||
성별 | 비긴트(20) | 예 | NULL | ||
나이 | 비긴트(20) | 예 | NULL | ||
관심 | varchar(255) | 예 | NULL | ||
생성_시간 | 날짜시간 | 예 | NULL | ||
업데이트_시간 | 날짜시간 | 예 | NULL | ||
삭제_시간 | 날짜시간 | 예 | NULL |
주요 분야
데이터베이스 테이블 구조
필드 | 유형 | 널 | 열쇠 | 기본 | 추가의 |
---|---|---|---|---|---|
ID | 비긴트(20) | 아니요 | PRI | NULL | 자동 증가 |
보낸 사람_ID | 비긴트(20) | 예 | NULL | ||
수신자_ID | 비긴트(20) | 예 | NULL | ||
콘텐츠 | varchar(255) | 예 | NULL | ||
send_time | 비긴트(20) | 예 | NULL | ||
생성_시간 | 날짜시간 | 예 | NULL | ||
업데이트_시간 | 날짜시간 | 예 | NULL | ||
삭제_시간 | 날짜시간 | 예 | NULL |
다음 구조는 개인적인 경험을 바탕으로 작성되었습니다. 부적절한 내용이 있으면 귀중한 의견을 보내주시기 바랍니다.
포조
이해하기 쉽고 데이터베이스에 해당하는 엔터티이지만 데이터베이스 필드와 일대일 대응이 필요하지 않습니다.
reqo(요청 객체), reso(응답 객체)
서로 다른 인터페이스를 통해 요청하는 경우 전달할 수 있는 매개변수와 응답 데이터도 다르기 때문에 각 인터페이스마다 해당 요청 엔터티와 응답 엔터티가 설계됩니다.
다음은 개인적인 이해입니다
제어 장치
주요 책임은 요청의 요청 매개변수를 수락하고, 이를 reqo로 변환하고, 간단한 요청 매개변수 확인을 수행하는 것입니다(내 개인적인 정의는 null이 아닌, 0이 아닌 등 데이터베이스와 관련 없는 확인입니다). pojo 결과를 얻기 위한 서비스 계층의 기능 및 pojo 결과 변환이 캡슐화되어 reso로 반환됩니다.
서비스
주요 책임은 Dao 레이어의 인터페이스를 추가로 캡슐화하고 컨트롤러가 호출할 수 있는 공통 인터페이스를 제공하는 것입니다. 반환된 데이터는 서비스에서 수행되어야 합니다. 사용자 이름이 반복됩니다).
다오
기본적으로 여기서 메서드는 아무런 확인 없이 SQL 문에 직접 해당합니다. 수신된 데이터는 신뢰할 수 있는 것으로 간주되며(컨트롤러 및 서비스 계층의 매개변수에 의해 확인됨) 반환된 데이터는 POJO일 수 있습니다.