Le texte commence par [ici](# texte), veuillez donc le sauter à moins que vous ne soyez membre du comité ONCT ICT.
Excusez-moi, mais je ne suis toujours pas familier avec les serveurs et les réseaux ~~ (étude) ~~ Je ne suis pas familier avec cela, alors veuillez le signaler aux professionnels.
・ On m'a demandé d'écrire un article sur exactement le même contenu ・ Je ne pouvais pas tant enseigner à mes juniors dans les conférences pendant les longues heures de vacances. ・ Recommandé par le président De. Surtout dans le département, je n'ai pas beaucoup de réalisations et je n'ai pas beaucoup d'éducation, alors j'ai pensé que je devais travailler un peu ici.
Dans les TIC, notamment avec le mot «Demandez à mes seniors», j'ai été obligé de construire soudainement un serveur SNS (sans même connaître l'adresse IP, encore moins AWS), j'ai donc pensé qu'il était nécessaire de partager des connaissances. (Je suis désolé si vous ne savez pas que c'est partagé)
Après cela, je veux diffuser encore plus Java, donc j'espère que vous l'utiliserez sur votre premier serveur.
Je suis presque autodidacte et je ne peux pas enseigner de connaissances de base, théoriques ou systématiques, mais au moins j'aimerais pouvoir vous montrer suffisamment de code pour exécuter un simple SNS et DCG.
Pour être honnête, ni le design ni le code ne sont utiles, mais j'espère qu'il pourra être utilisé pour sortir de la situation où les débutants ne connaissent pas les termes de google et ne connaissent pas la syntaxe minimale.
Au début, je l'ai écrit avec enthousiasme, mais quand j'ai fini d'écrire le aparté, je ne pouvais pas voir la fin, et ma motivation a diminué, alors je l'ai écrit grossièrement. Les plaintes sont acceptées dans les commentaires. De plus, en ce qui concerne SQL, cette fois, il était difficile d'écrire ~~, donc je l'ai omis ~~.
En gros, écrivez un programme qui reçoit une chaîne de caractères du client (côté exploitation (HTML, application Android, etc.)) et renvoie le résultat du traitement sous forme de chaîne de caractères.
Il existe une API pour le développement de serveurs appelée JavaEE. Si vous utilisez un conteneur Web tel que Tomcat, vous pouvez le publier et interagir avec d'autres programmes (ou ordinateurs).
Cette fois, je vais expliquer HTTP et WebSocket (WS). HTTP retourne essentiellement le traitement lorsqu'un message est reçu. (La communication est interrompue) WS conserve la connexion une fois connecté et s'envoie des messages. (La communication n'est pas interrompue)
Les deux projets que j'ai expérimentés sont les suivants.
-Lorsque vous appuyez sur le bouton de publication sur le client (application Android), le contenu (ID, contenu de publication, informations de localisation, etc.) sera envoyé au serveur, alors enregistrez-le dans SQL. -Lorsque vous appuyez sur le bouton de lecture sur le client, un message indiquant la lecture sera envoyé. -Le serveur lit le message que l'utilisateur peut afficher à partir de SQL et le renvoie.
-Lorsque le client démarre, il se connecte d'abord au serveur. -Les opérations effectuées par le client sont envoyées au serveur une par une. -Le serveur dispose d'un programme de jeu et exploite le jeu en fonction des données envoyées. -Lorsque l'opération est terminée, le résultat du traitement est envoyé au client et le client dessine en fonction de celui-ci.
Tout d'abord, l'environnement est le suivant.
Logiciel(Tel) | |
---|---|
langage de développement | Java (8 recommandé) |
API de servlet | JavaEE |
IDE | IntelliJ Community |
Conteneur Web | Tomcat |
Outil de création | Gradle |
J'ai écrit à propos de ces configurations dans un article séparé, alors volez-y. (Je suis désolé)
Cliquez avec le bouton droit sur src-> main-> java et cliquez sur Nouveau-> Package pour créer le package. Cliquez ensuite avec le bouton droit de la souris sur le bas du package et sélectionnez Nouveau-> Fichier Java pour créer un fichier .java.
Comme mentionné dans l'article Préférences, la communauté IntelliJ n'a pas de fonctionnalités liées au démarrage du serveur, nous allons donc remplacer la tâche de Gradle pour l'exécution. Cliquez sur Gradle à l'extrême droite de l'écran pour afficher une liste de tâches. Je pense qu'il y a un élément appelé Tomcat Run dans gretty. Vous pouvez démarrer le serveur en double-cliquant dessus.
org.apache.catalina.LifecycleException: Protocol handler initialization failed
at org.apache.catalina.connector.Connector.initInternal(Connector.java:935)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136)
at org.apache.catalina.core.StandardService.initInternal(StandardService.java:530)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136)
at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:852)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:173)
at org.apache.catalina.startup.Tomcat.start(Tomcat.java:371)
at org.apache.catalina.startup.Tomcat$start$0.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120)
at org.akhikhl.gretty.TomcatServerManager.startServer(TomcatServerManager.groovy:49)
at org.akhikhl.gretty.ServerManager$startServer$0.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:128)
at org.akhikhl.gretty.Runner.run(Runner.groovy:117)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:210)
at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.call(PogoMetaMethodSite.java:71)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120)
at org.akhikhl.gretty.Runner.main(Runner.groovy:44)
Caused by: java.net.BindException: Address already in use: bind
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:433)
at sun.nio.ch.Net.bind(Net.java:425)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
at org.apache.tomcat.util.net.NioEndpoint.initServerSocket(NioEndpoint.java:227)
at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:202)
at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:1043)
at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:540)
at org.apache.coyote.http11.AbstractHttp11Protocol.init(AbstractHttp11Protocol.java:74)
at org.apache.catalina.connector.Connector.initInternal(Connector.java:932)
... 27 more
http://localhost:8080/ Et accédons ici Si Not Found est affiché comme ceci, cela réussit. Je n'ai encore écrit aucun programme, c'est donc naturel. En passant, si vous ne l'exécutez pas, une erreur de chargement de page etc. sera affichée.
Un servlet est comme le programme principal d'un serveur (approprié) Ici, nous allons introduire Http avant WS.
Il existe une méthode en Http, qui est utilisée correctement en fonction du contenu de la communication, mais ici seul GET est utilisé pour simplifier. (Pardon) GET est une méthode qui demande des ressources, etc. au serveur. Il se présente sous la forme de transmission de traitement et de données à l'aide d'URL et de paramètres, et de réception des résultats d'exécution.
Créons d'abord un programme de servlet avec HttpServlet.java. (Le nom de la classe est gratuit)
Dans Tomcat, c'est une bonne pratique d'écrire un fichier de paramètres appelé web.xml, mais il semble que les annotations puissent être utilisées à la place, donc cette fois je le ferai.
Le contenu est affiché dans le code ci-dessous.
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.annotation.WebServlet;
//Obligatoire
//Transmettez le nom du servlet dans name et une liste d'URL qui accèdent à urlPatterns.
//Vous pouvez également spécifier un caractère générique.
@WebServlet(
name = "HttpServlet",
urlPatterns = {"/*"})
@MultipartConfig (
fileSizeThreshold= 32768 ,
maxFileSize= 5242880 ,
maxRequestSize= 27262976
)
// javax.servlet.http.Peut être utilisé comme servlet en héritant de HttpServlet
public class HttpServlet extends javax.servlet.http.HttpServlet {
//La méthode qui est appelée lorsque la méthode doGet reçoit une requête GET
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response){
PrintWriter out = null;
try {
//Cette zone est magique pour le moment.
//Code de caractère et ainsi de suite
response.setContentType("text/html; charset=UTF-8");
response.setHeader("Access-Control-Allow-Origin", "*");
request.setCharacterEncoding("utf-8");
//En obtenant PrintWiter, System.out.println()Vous pouvez renvoyer une chaîne de caractères comme celle-ci.
out = response.getWriter();
// request.getServletPath();Reçoit le chemin entré ci-dessous à partir de la racine de ce projet.
//Cette fois, branchez de manière appropriée avec un interrupteur.
String path = request.getServletPath();
String str = null;
switch(path){
case "/hoge":
// request.getParameter()Recevez les paramètres à.
// http://localhost:8080/Test/hoge?str=hage&str2=hige
//URL comme?str=hage&str2=partie hige
str = request.getParameter("str");
break;
case "/huga":
str = "huga";
break;
}
//Renvoyez le contenu de str.
out.println(str);
//Appelez également flush correctement.
out.flush();
} catch (IOException e){
e.printStackTrace();
}
}
}
Si vous faites cela et marchez sur une URL comme celle ci-dessous, vous reviendrez aaa.
[http: // localhost: 8080 /
Cette fois, j'écrirai un servlet qui utilise WebSocket au lieu de Http. Http était une méthode qui répond à la communication du client (de base) (établit une nouvelle connexion à chaque fois), WebSocket maintient la communication avec le client et communique dans les deux sens.
package scptcg.server;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
//Avec cela, il devient un serveur WebSocket
//L'URL peut être un caractère générique
@ServerEndpoint("/ws")
public final class WSEndPoint {
// Session(la communication)Carte à enregistrer
private static Map<String, Session> session = new HashMap<>();
//Méthode appelée lors de la connexion
@OnOpen
public void onOpen(final Session client, final EndpointConfig config) {
String log = client.getId() + " was connected.";
System.out.println(log);
}
//Méthode appelée lors de la déconnexion
@OnClose
public void onClose(final Session client, final CloseReason reason) throws IOException {
String log = client.getId() + " was closed by "
+ reason.getCloseCode() + "[" + reason.getCloseCode().getCode() + "]";
System.out.println(log);
}
//Méthode appelée en cas d'erreur
@OnError
public void onError(final Session client, final Throwable error) {
String log = client.getId() + " was error. [" + error.getMessage() + "]";
error.printStackTrace();
}
//Méthode appelée lors de l'envoi d'un message
@OnMessage
public void onMessage(final String text, final Session client) throws IOException {
//On suppose que le contenu du message décrit l'opération, l'identifiant et les données séparés par des sauts de ligne.
String[] t = text.split("\n");
String event = t[0];
String id = t[1];
//Branche pour chaque contenu d'événement
switch (event){
case "login":
//Enregistrez la session dans HashMap.
session.put(id, client);
//Envoyez une chaîne à la session enregistrée avec l'ID.
session.get(id).getBasicRemote().sendText(id);
System.out.println(id);
break;
case "commit":
//diffuser
for (Session s :session.values()){
s.getBasicRemote().sendText(t[2]);
}
System.out.println(t[2]);
break;
case "close":
//Supprimer de la liste des sessions
session.remove(t[1]);
break;
}
}
}
Cela se fait dans la méthode OnMessage (). Il semble qu'il n'y ait pas de branche du contenu de traitement à l'origine, donc je pense qu'il est préférable de le transmettre au début du contenu de communication. Au fait, puisqu'il s'agit d'un échantillon, il s'agit de ~~ putain de ~~ données séparées par des sauts de ligne, mais j'utilise généralement Gson pour échanger JSON. Les annotations telles que @OnMessage reconnaissent la méthode appelée, il n'est donc pas nécessaire d'hériter d'une classe spéciale. ~~ C'est gênant, je vais donc omettre Gson également.
Je mettrai également le HTML pour le test. Cependant, je ne l'ai pas testé, donc je pense qu'il vaut mieux l'écrire vous-même.
<!DOCTYPE html>
<html>
<head>
<title>WebSocket Sample</title>
<script type="text/javascript">
var uri = "ws://localhost:8080/Project/";
//Objet WebSocket
var webSocket = null;
//Traitement initial
function init() {
if (webSocket == null) {
//Initialisation WebSocket
webSocket = new WebSocket(uri);
//Paramètres du gestionnaire d'événements
webSocket.onopen = onOpen;
webSocket.onmessage = onMessage;
webSocket.onclose = onClose;
webSocket.onerror = onError;
webSocket.send("login\n" + document.getElementById('id').innerText);
}
}
function onOpen(event) {
alert('open');
}
//Événement de réception de message
function onMessage(event) {
document.getElementById('box').innerText += event;
}
//Événement d'erreur
function onError(event) {
alert('error');
}
//Événement de déconnexion
function onClose(event) {
alert('close');
webSocket = null;
}
function send(){
webSocket.send("commit\n" + document.getElementById('txt').innerText);
}
</script>
</head>
<body>
<input type="id" name="name" size="30" maxlength="20" />
<input type="txt" name="name" size="30" maxlength="20" />
<hr />
<input id="box" type="text" data-name="message" size="100" />
<hr />
<button id="con" onclick="init()">init</button>
<button id="send" onclick="send()">send</button>
</body>
</html>
À propos, l'URL est [ws: // localhost: 8080 /
Je suis désolé, je suis en désordre Je vais mettre le code SNS et DCG sur mon GitHub, alors jetez un œil. ~~ (Je suis surpris de la putain de code) ~~
Je l'ai écrit sérieusement, donc si vous avez une demande de correction ou d'explication supplémentaire, dites-le directement ou sur SNS ~~ et écrivez-le dans le commentaire.
Passez un bon Noël à tous!
Recommended Posts