中文文档: README.md
Forked from https://github.com/mheath/netty-mysql-codec
This project is useful on:
- Implementing a database and making it ready to connect with MySQL compatible clients.
- Proxy an arbitrary data source and make it act as a MySQL server.
- Studying on MySQL Protocol.
To make sure the downloaded codes are complete, you can run MySqlListenerTest.java to see if it can be passed successfully.
The test first runs a MySQL server with any queries resulting 'Hello World !'. Then it raises a JDBC connection and send a SQL to the server, checks the result and finally closes the server.
The first thing you need to do is implementing a SqlEngine
public class YourSqlEngine implements SqlEngine {
}
To respond SQLs from the client, you need to implement query().
@Override
public void query(ResultSetWriter resultSetWriter, String database, String userName, byte[] scramble411, byte[] authSeed, String sql) throws IOException {
// Build a result returning just one string column named 'col1'
// writeColumns() must be called before any invoking of writeRow()
resultSetWriter.writeColumns(List.of(new QueryResultColumn("col1", "varchar(255)")));
// Return just one row with content 'Hello World !'
resultSetWriter.writeRow(List.of("Hello World !"));
// Do not forget to finish the response
resultSetWriter.finish();
}
To protect your server from disallowed visiting, you need to implement authenticate().
@Override
public void authenticate(String database, String userName, byte[] scramble411, byte[] authSeed) throws IOException {
// Block user if not named 'github'
String validUser = "github";
if (!userName.equals(validUser)) {
throw new IOException(new IllegalAccessException("Authentication failed: User " + userName + " is not allowed to connect"));
}
// Check if the password is '123456'
String validPassword = "123456";
// SHA1 and encode the password
String validPasswordSha1 = SHAUtils.SHA(validPassword, SHAUtils.SHA_1);
String validScramble411WithSeed20 = Utils.scramble411(validPasswordSha1, authSeed);
// Compare and throw an exception if needed
if (!Utils.compareDigest(validScramble411WithSeed20, Base64.getEncoder().encodeToString(scramble411))) {
throw new IOException(new IllegalAccessException("Authentication failed: Validation failed"));
}
}
Once the engine definition is ready, you can pass it into MySqlListener and then it will start listening a TCP port.
// Start and listen port 3307
new MySqlListener(3307, 100, new YourSqlEngine());
// For test you can sleep for a while so you have enough time to connect to it.
Thread.sleep(1000L * 60 * 10);
After starting of the server, you can open any favorite MySQL client to connect to it.
mysql -h127.0.0.1 -P3307 -ugithub -p123456 dummy_db
> select * from dummy_table;
+---------------+
| col1 |
+---------------+
| Hello World ! |
+---------------+
1 row in set (0.006 sec)
This project is under the Apache 2.0 license. See the LICENSE file for details.
- Thanks mheath for providing beautiful implementation codes.
- Minimal version of Java: JDK11. (JDK8 under testing)
- Contact - Wechat: 95634620 Mail: unrealwalker@126.com